diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /net/bridge/br_input.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'net/bridge/br_input.c')
-rw-r--r-- | net/bridge/br_input.c | 48 |
1 files changed, 30 insertions, 18 deletions
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 826cd5221536..f06ee39c73fd 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c | |||
@@ -21,6 +21,10 @@ | |||
21 | /* Bridge group multicast address 802.1d (pg 51). */ | 21 | /* Bridge group multicast address 802.1d (pg 51). */ |
22 | const u8 br_group_address[ETH_ALEN] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 }; | 22 | const u8 br_group_address[ETH_ALEN] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 }; |
23 | 23 | ||
24 | /* Hook for brouter */ | ||
25 | br_should_route_hook_t __rcu *br_should_route_hook __read_mostly; | ||
26 | EXPORT_SYMBOL(br_should_route_hook); | ||
27 | |||
24 | static int br_pass_frame_up(struct sk_buff *skb) | 28 | static int br_pass_frame_up(struct sk_buff *skb) |
25 | { | 29 | { |
26 | struct net_device *indev, *brdev = BR_INPUT_SKB_CB(skb)->brdev; | 30 | struct net_device *indev, *brdev = BR_INPUT_SKB_CB(skb)->brdev; |
@@ -56,7 +60,7 @@ int br_handle_frame_finish(struct sk_buff *skb) | |||
56 | br = p->br; | 60 | br = p->br; |
57 | br_fdb_update(br, p, eth_hdr(skb)->h_source); | 61 | br_fdb_update(br, p, eth_hdr(skb)->h_source); |
58 | 62 | ||
59 | if (is_multicast_ether_addr(dest) && | 63 | if (!is_broadcast_ether_addr(dest) && is_multicast_ether_addr(dest) && |
60 | br_multicast_rcv(br, p, skb)) | 64 | br_multicast_rcv(br, p, skb)) |
61 | goto drop; | 65 | goto drop; |
62 | 66 | ||
@@ -73,10 +77,12 @@ int br_handle_frame_finish(struct sk_buff *skb) | |||
73 | 77 | ||
74 | dst = NULL; | 78 | dst = NULL; |
75 | 79 | ||
76 | if (is_multicast_ether_addr(dest)) { | 80 | if (is_broadcast_ether_addr(dest)) |
81 | skb2 = skb; | ||
82 | else if (is_multicast_ether_addr(dest)) { | ||
77 | mdst = br_mdb_get(br, skb); | 83 | mdst = br_mdb_get(br, skb); |
78 | if (mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) { | 84 | if (mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) { |
79 | if ((mdst && !hlist_unhashed(&mdst->mglist)) || | 85 | if ((mdst && mdst->mglist) || |
80 | br_multicast_is_router(br)) | 86 | br_multicast_is_router(br)) |
81 | skb2 = skb; | 87 | skb2 = skb; |
82 | br_multicast_forward(mdst, skb, skb2); | 88 | br_multicast_forward(mdst, skb, skb2); |
@@ -94,9 +100,10 @@ int br_handle_frame_finish(struct sk_buff *skb) | |||
94 | } | 100 | } |
95 | 101 | ||
96 | if (skb) { | 102 | if (skb) { |
97 | if (dst) | 103 | if (dst) { |
104 | dst->used = jiffies; | ||
98 | br_forward(dst->dst, skb, skb2); | 105 | br_forward(dst->dst, skb, skb2); |
99 | else | 106 | } else |
100 | br_flood_forward(br, skb, skb2); | 107 | br_flood_forward(br, skb, skb2); |
101 | } | 108 | } |
102 | 109 | ||
@@ -135,21 +142,22 @@ static inline int is_link_local(const unsigned char *dest) | |||
135 | * Return NULL if skb is handled | 142 | * Return NULL if skb is handled |
136 | * note: already called with rcu_read_lock | 143 | * note: already called with rcu_read_lock |
137 | */ | 144 | */ |
138 | struct sk_buff *br_handle_frame(struct sk_buff *skb) | 145 | rx_handler_result_t br_handle_frame(struct sk_buff **pskb) |
139 | { | 146 | { |
140 | struct net_bridge_port *p; | 147 | struct net_bridge_port *p; |
148 | struct sk_buff *skb = *pskb; | ||
141 | const unsigned char *dest = eth_hdr(skb)->h_dest; | 149 | const unsigned char *dest = eth_hdr(skb)->h_dest; |
142 | int (*rhook)(struct sk_buff *skb); | 150 | br_should_route_hook_t *rhook; |
143 | 151 | ||
144 | if (skb->pkt_type == PACKET_LOOPBACK) | 152 | if (unlikely(skb->pkt_type == PACKET_LOOPBACK)) |
145 | return skb; | 153 | return RX_HANDLER_PASS; |
146 | 154 | ||
147 | if (!is_valid_ether_addr(eth_hdr(skb)->h_source)) | 155 | if (!is_valid_ether_addr(eth_hdr(skb)->h_source)) |
148 | goto drop; | 156 | goto drop; |
149 | 157 | ||
150 | skb = skb_share_check(skb, GFP_ATOMIC); | 158 | skb = skb_share_check(skb, GFP_ATOMIC); |
151 | if (!skb) | 159 | if (!skb) |
152 | return NULL; | 160 | return RX_HANDLER_CONSUMED; |
153 | 161 | ||
154 | p = br_port_get_rcu(skb->dev); | 162 | p = br_port_get_rcu(skb->dev); |
155 | 163 | ||
@@ -163,19 +171,23 @@ struct sk_buff *br_handle_frame(struct sk_buff *skb) | |||
163 | goto forward; | 171 | goto forward; |
164 | 172 | ||
165 | if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev, | 173 | if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev, |
166 | NULL, br_handle_local_finish)) | 174 | NULL, br_handle_local_finish)) { |
167 | return NULL; /* frame consumed by filter */ | 175 | return RX_HANDLER_CONSUMED; /* consumed by filter */ |
168 | else | 176 | } else { |
169 | return skb; /* continue processing */ | 177 | *pskb = skb; |
178 | return RX_HANDLER_PASS; /* continue processing */ | ||
179 | } | ||
170 | } | 180 | } |
171 | 181 | ||
172 | forward: | 182 | forward: |
173 | switch (p->state) { | 183 | switch (p->state) { |
174 | case BR_STATE_FORWARDING: | 184 | case BR_STATE_FORWARDING: |
175 | rhook = rcu_dereference(br_should_route_hook); | 185 | rhook = rcu_dereference(br_should_route_hook); |
176 | if (rhook != NULL) { | 186 | if (rhook) { |
177 | if (rhook(skb)) | 187 | if ((*rhook)(skb)) { |
178 | return skb; | 188 | *pskb = skb; |
189 | return RX_HANDLER_PASS; | ||
190 | } | ||
179 | dest = eth_hdr(skb)->h_dest; | 191 | dest = eth_hdr(skb)->h_dest; |
180 | } | 192 | } |
181 | /* fall through */ | 193 | /* fall through */ |
@@ -190,5 +202,5 @@ forward: | |||
190 | drop: | 202 | drop: |
191 | kfree_skb(skb); | 203 | kfree_skb(skb); |
192 | } | 204 | } |
193 | return NULL; | 205 | return RX_HANDLER_CONSUMED; |
194 | } | 206 | } |