X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=net%2Fcore%2Fdev.c;h=ef56c035d44e5dae7d448c6b27966dc62a5930f1;hb=489447380a2921ec0e9154f773c44ab3167ede4b;hp=bf66b114d3c235b24457bc588d34a12e60b7ffd5;hpb=977127174a7dff52d17faeeb4c4949a54221881f;p=linux-2.6 diff --git a/net/core/dev.c b/net/core/dev.c index bf66b114d3..ef56c035d4 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -75,6 +75,7 @@ #include #include #include +#include #include #include #include @@ -109,10 +110,8 @@ #include #include #include -#ifdef CONFIG_NET_RADIO -#include /* Note : will define WIRELESS_EXT */ +#include #include -#endif /* CONFIG_NET_RADIO */ #include /* @@ -1447,8 +1446,29 @@ static inline struct net_device *skb_bond(struct sk_buff *skb) { struct net_device *dev = skb->dev; - if (dev->master) + if (dev->master) { + /* + * On bonding slaves other than the currently active + * slave, suppress duplicates except for 802.3ad + * ETH_P_SLOW and alb non-mcast/bcast. + */ + if (dev->priv_flags & IFF_SLAVE_INACTIVE) { + if (dev->master->priv_flags & IFF_MASTER_ALB) { + if (skb->pkt_type != PACKET_BROADCAST && + skb->pkt_type != PACKET_MULTICAST) + goto keep; + } + + if (dev->master->priv_flags & IFF_MASTER_8023AD && + skb->protocol == __constant_htons(ETH_P_SLOW)) + goto keep; + + kfree_skb(skb); + return NULL; + } +keep: skb->dev = dev->master; + } return dev; } @@ -1592,6 +1612,9 @@ int netif_receive_skb(struct sk_buff *skb) orig_dev = skb_bond(skb); + if (!orig_dev) + return NET_RX_DROP; + __get_cpu_var(netdev_rx_stat).total++; skb->h.raw = skb->nh.raw = skb->data; @@ -2027,7 +2050,7 @@ static struct file_operations softnet_seq_fops = { .release = seq_release, }; -#ifdef WIRELESS_EXT +#ifdef CONFIG_WIRELESS_EXT extern int wireless_proc_init(void); #else #define wireless_proc_init() 0 @@ -2542,13 +2565,14 @@ int dev_ioctl(unsigned int cmd, void __user *arg) case SIOCBONDENSLAVE: case SIOCBONDRELEASE: case SIOCBONDSETHWADDR: - case SIOCBONDSLAVEINFOQUERY: - case SIOCBONDINFOQUERY: case SIOCBONDCHANGEACTIVE: case SIOCBRADDIF: case SIOCBRDELIF: if (!capable(CAP_NET_ADMIN)) return -EPERM; + /* fall through */ + case SIOCBONDSLAVEINFOQUERY: + case SIOCBONDINFOQUERY: dev_load(ifr.ifr_name); rtnl_lock(); ret = dev_ifsioc(&ifr, cmd); @@ -2580,7 +2604,7 @@ int dev_ioctl(unsigned int cmd, void __user *arg) ret = -EFAULT; return ret; } -#ifdef WIRELESS_EXT +#ifdef CONFIG_WIRELESS_EXT /* Take care of Wireless Extensions */ if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) { /* If command is `set a parameter', or @@ -2601,7 +2625,7 @@ int dev_ioctl(unsigned int cmd, void __user *arg) ret = -EFAULT; return ret; } -#endif /* WIRELESS_EXT */ +#endif /* CONFIG_WIRELESS_EXT */ return -EINVAL; } } @@ -3235,7 +3259,7 @@ static int __init net_dev_init(void) * Initialise the packet receive queues. */ - for (i = 0; i < NR_CPUS; i++) { + for_each_cpu(i) { struct softnet_data *queue; queue = &per_cpu(softnet_data, i);