aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-02-28 13:48:59 -0500
committerDavid S. Miller <davem@davemloft.net>2011-02-28 13:48:59 -0500
commit63d8ea7f93e1fb9d1aa9509ab3e1a71199245c80 (patch)
treee862a2af5859ed15bef41adcebc76462aeff7859 /net
parent5b2c4dd2ec12cf0e53b2bd2926f0fe2d1fbb4eda (diff)
net: Forgot to commit net/core/dev.c part of Jiri's ->rx_handler patch.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/core/dev.c119
1 files changed, 31 insertions, 88 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index 69a3c0817d6f..30440e7b296c 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3096,63 +3096,31 @@ void netdev_rx_handler_unregister(struct net_device *dev)
3096} 3096}
3097EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister); 3097EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister);
3098 3098
3099static inline void skb_bond_set_mac_by_master(struct sk_buff *skb, 3099static void vlan_on_bond_hook(struct sk_buff *skb)
3100 struct net_device *master)
3101{ 3100{
3102 if (skb->pkt_type == PACKET_HOST) { 3101 /*
3103 u16 *dest = (u16 *) eth_hdr(skb)->h_dest; 3102 * Make sure ARP frames received on VLAN interfaces stacked on
3103 * bonding interfaces still make their way to any base bonding
3104 * device that may have registered for a specific ptype.
3105 */
3106 if (skb->dev->priv_flags & IFF_802_1Q_VLAN &&
3107 vlan_dev_real_dev(skb->dev)->priv_flags & IFF_BONDING &&
3108 skb->protocol == htons(ETH_P_ARP)) {
3109 struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
3104 3110
3105 memcpy(dest, master->dev_addr, ETH_ALEN); 3111 if (!skb2)
3112 return;
3113 skb2->dev = vlan_dev_real_dev(skb->dev);
3114 netif_rx(skb2);
3106 } 3115 }
3107} 3116}
3108 3117
3109/* On bonding slaves other than the currently active slave, suppress
3110 * duplicates except for 802.3ad ETH_P_SLOW, alb non-mcast/bcast, and
3111 * ARP on active-backup slaves with arp_validate enabled.
3112 */
3113static int __skb_bond_should_drop(struct sk_buff *skb,
3114 struct net_device *master)
3115{
3116 struct net_device *dev = skb->dev;
3117
3118 if (master->priv_flags & IFF_MASTER_ARPMON)
3119 dev->last_rx = jiffies;
3120
3121 if ((master->priv_flags & IFF_MASTER_ALB) &&
3122 (master->priv_flags & IFF_BRIDGE_PORT)) {
3123 /* Do address unmangle. The local destination address
3124 * will be always the one master has. Provides the right
3125 * functionality in a bridge.
3126 */
3127 skb_bond_set_mac_by_master(skb, master);
3128 }
3129
3130 if (dev->priv_flags & IFF_SLAVE_INACTIVE) {
3131 if ((dev->priv_flags & IFF_SLAVE_NEEDARP) &&
3132 skb->protocol == __cpu_to_be16(ETH_P_ARP))
3133 return 0;
3134
3135 if (master->priv_flags & IFF_MASTER_ALB) {
3136 if (skb->pkt_type != PACKET_BROADCAST &&
3137 skb->pkt_type != PACKET_MULTICAST)
3138 return 0;
3139 }
3140 if (master->priv_flags & IFF_MASTER_8023AD &&
3141 skb->protocol == __cpu_to_be16(ETH_P_SLOW))
3142 return 0;
3143
3144 return 1;
3145 }
3146 return 0;
3147}
3148
3149static int __netif_receive_skb(struct sk_buff *skb) 3118static int __netif_receive_skb(struct sk_buff *skb)
3150{ 3119{
3151 struct packet_type *ptype, *pt_prev; 3120 struct packet_type *ptype, *pt_prev;
3152 rx_handler_func_t *rx_handler; 3121 rx_handler_func_t *rx_handler;
3153 struct net_device *orig_dev; 3122 struct net_device *orig_dev;
3154 struct net_device *null_or_orig; 3123 struct net_device *null_or_dev;
3155 struct net_device *orig_or_bond;
3156 int ret = NET_RX_DROP; 3124 int ret = NET_RX_DROP;
3157 __be16 type; 3125 __be16 type;
3158 3126
@@ -3167,32 +3135,8 @@ static int __netif_receive_skb(struct sk_buff *skb)
3167 3135
3168 if (!skb->skb_iif) 3136 if (!skb->skb_iif)
3169 skb->skb_iif = skb->dev->ifindex; 3137 skb->skb_iif = skb->dev->ifindex;
3170
3171 /*
3172 * bonding note: skbs received on inactive slaves should only
3173 * be delivered to pkt handlers that are exact matches. Also
3174 * the deliver_no_wcard flag will be set. If packet handlers
3175 * are sensitive to duplicate packets these skbs will need to
3176 * be dropped at the handler.
3177 */
3178 null_or_orig = NULL;
3179 orig_dev = skb->dev; 3138 orig_dev = skb->dev;
3180 if (skb->deliver_no_wcard)
3181 null_or_orig = orig_dev;
3182 else if (netif_is_bond_slave(orig_dev)) {
3183 struct net_device *bond_master = ACCESS_ONCE(orig_dev->master);
3184
3185 if (likely(bond_master)) {
3186 if (__skb_bond_should_drop(skb, bond_master)) {
3187 skb->deliver_no_wcard = 1;
3188 /* deliver only exact match */
3189 null_or_orig = orig_dev;
3190 } else
3191 skb->dev = bond_master;
3192 }
3193 }
3194 3139
3195 __this_cpu_inc(softnet_data.processed);
3196 skb_reset_network_header(skb); 3140 skb_reset_network_header(skb);
3197 skb_reset_transport_header(skb); 3141 skb_reset_transport_header(skb);
3198 skb->mac_len = skb->network_header - skb->mac_header; 3142 skb->mac_len = skb->network_header - skb->mac_header;
@@ -3201,6 +3145,10 @@ static int __netif_receive_skb(struct sk_buff *skb)
3201 3145
3202 rcu_read_lock(); 3146 rcu_read_lock();
3203 3147
3148another_round:
3149
3150 __this_cpu_inc(softnet_data.processed);
3151
3204#ifdef CONFIG_NET_CLS_ACT 3152#ifdef CONFIG_NET_CLS_ACT
3205 if (skb->tc_verd & TC_NCLS) { 3153 if (skb->tc_verd & TC_NCLS) {
3206 skb->tc_verd = CLR_TC_NCLS(skb->tc_verd); 3154 skb->tc_verd = CLR_TC_NCLS(skb->tc_verd);
@@ -3209,8 +3157,7 @@ static int __netif_receive_skb(struct sk_buff *skb)
3209#endif 3157#endif
3210 3158
3211 list_for_each_entry_rcu(ptype, &ptype_all, list) { 3159 list_for_each_entry_rcu(ptype, &ptype_all, list) {
3212 if (ptype->dev == null_or_orig || ptype->dev == skb->dev || 3160 if (!ptype->dev || ptype->dev == skb->dev) {
3213 ptype->dev == orig_dev) {
3214 if (pt_prev) 3161 if (pt_prev)
3215 ret = deliver_skb(skb, pt_prev, orig_dev); 3162 ret = deliver_skb(skb, pt_prev, orig_dev);
3216 pt_prev = ptype; 3163 pt_prev = ptype;
@@ -3224,16 +3171,20 @@ static int __netif_receive_skb(struct sk_buff *skb)
3224ncls: 3171ncls:
3225#endif 3172#endif
3226 3173
3227 /* Handle special case of bridge or macvlan */
3228 rx_handler = rcu_dereference(skb->dev->rx_handler); 3174 rx_handler = rcu_dereference(skb->dev->rx_handler);
3229 if (rx_handler) { 3175 if (rx_handler) {
3176 struct net_device *prev_dev;
3177
3230 if (pt_prev) { 3178 if (pt_prev) {
3231 ret = deliver_skb(skb, pt_prev, orig_dev); 3179 ret = deliver_skb(skb, pt_prev, orig_dev);
3232 pt_prev = NULL; 3180 pt_prev = NULL;
3233 } 3181 }
3182 prev_dev = skb->dev;
3234 skb = rx_handler(skb); 3183 skb = rx_handler(skb);
3235 if (!skb) 3184 if (!skb)
3236 goto out; 3185 goto out;
3186 if (skb->dev != prev_dev)
3187 goto another_round;
3237 } 3188 }
3238 3189
3239 if (vlan_tx_tag_present(skb)) { 3190 if (vlan_tx_tag_present(skb)) {
@@ -3248,24 +3199,16 @@ ncls:
3248 goto out; 3199 goto out;
3249 } 3200 }
3250 3201
3251 /* 3202 vlan_on_bond_hook(skb);
3252 * Make sure frames received on VLAN interfaces stacked on 3203
3253 * bonding interfaces still make their way to any base bonding 3204 /* deliver only exact match when indicated */
3254 * device that may have registered for a specific ptype. The 3205 null_or_dev = skb->deliver_no_wcard ? skb->dev : NULL;
3255 * handler may have to adjust skb->dev and orig_dev.
3256 */
3257 orig_or_bond = orig_dev;
3258 if ((skb->dev->priv_flags & IFF_802_1Q_VLAN) &&
3259 (vlan_dev_real_dev(skb->dev)->priv_flags & IFF_BONDING)) {
3260 orig_or_bond = vlan_dev_real_dev(skb->dev);
3261 }
3262 3206
3263 type = skb->protocol; 3207 type = skb->protocol;
3264 list_for_each_entry_rcu(ptype, 3208 list_for_each_entry_rcu(ptype,
3265 &ptype_base[ntohs(type) & PTYPE_HASH_MASK], list) { 3209 &ptype_base[ntohs(type) & PTYPE_HASH_MASK], list) {
3266 if (ptype->type == type && (ptype->dev == null_or_orig || 3210 if (ptype->type == type &&
3267 ptype->dev == skb->dev || ptype->dev == orig_dev || 3211 (ptype->dev == null_or_dev || ptype->dev == skb->dev)) {
3268 ptype->dev == orig_or_bond)) {
3269 if (pt_prev) 3212 if (pt_prev)
3270 ret = deliver_skb(skb, pt_prev, orig_dev); 3213 ret = deliver_skb(skb, pt_prev, orig_dev);
3271 pt_prev = ptype; 3214 pt_prev = ptype;