diff options
author | David S. Miller <davem@davemloft.net> | 2011-02-28 13:48:59 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-02-28 13:48:59 -0500 |
commit | 63d8ea7f93e1fb9d1aa9509ab3e1a71199245c80 (patch) | |
tree | e862a2af5859ed15bef41adcebc76462aeff7859 /net | |
parent | 5b2c4dd2ec12cf0e53b2bd2926f0fe2d1fbb4eda (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.c | 119 |
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 | } |
3097 | EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister); | 3097 | EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister); |
3098 | 3098 | ||
3099 | static inline void skb_bond_set_mac_by_master(struct sk_buff *skb, | 3099 | static 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 | */ | ||
3113 | static 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 | |||
3149 | static int __netif_receive_skb(struct sk_buff *skb) | 3118 | static 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 | ||
3148 | another_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) | |||
3224 | ncls: | 3171 | ncls: |
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; |