@@ -279,8 +279,17 @@ int br_nf_pre_routing_finish_bridge(struct net *net, struct sock *sk, struct sk_
279279
280280 if ((READ_ONCE (neigh -> nud_state ) & NUD_CONNECTED ) &&
281281 READ_ONCE (neigh -> hh .hh_len )) {
282+ struct net_device * br_indev ;
283+
284+ br_indev = nf_bridge_get_physindev (skb , net );
285+ if (!br_indev ) {
286+ neigh_release (neigh );
287+ goto free_skb ;
288+ }
289+
282290 neigh_hh_bridge (& neigh -> hh , skb );
283- skb -> dev = nf_bridge -> physindev ;
291+ skb -> dev = br_indev ;
292+
284293 ret = br_handle_frame_finish (net , sk , skb );
285294 } else {
286295 /* the neighbour function below overwrites the complete
@@ -352,12 +361,18 @@ br_nf_ipv4_daddr_was_changed(const struct sk_buff *skb,
352361 */
353362static int br_nf_pre_routing_finish (struct net * net , struct sock * sk , struct sk_buff * skb )
354363{
355- struct net_device * dev = skb -> dev ;
364+ struct net_device * dev = skb -> dev , * br_indev ;
356365 struct iphdr * iph = ip_hdr (skb );
357366 struct nf_bridge_info * nf_bridge = nf_bridge_info_get (skb );
358367 struct rtable * rt ;
359368 int err ;
360369
370+ br_indev = nf_bridge_get_physindev (skb , net );
371+ if (!br_indev ) {
372+ kfree_skb (skb );
373+ return 0 ;
374+ }
375+
361376 nf_bridge -> frag_max_size = IPCB (skb )-> frag_max_size ;
362377
363378 if (nf_bridge -> pkt_otherhost ) {
@@ -397,7 +412,7 @@ static int br_nf_pre_routing_finish(struct net *net, struct sock *sk, struct sk_
397412 } else {
398413 if (skb_dst (skb )-> dev == dev ) {
399414bridged_dnat :
400- skb -> dev = nf_bridge -> physindev ;
415+ skb -> dev = br_indev ;
401416 nf_bridge_update_protocol (skb );
402417 nf_bridge_push_encap_header (skb );
403418 br_nf_hook_thresh (NF_BR_PRE_ROUTING ,
@@ -410,7 +425,7 @@ static int br_nf_pre_routing_finish(struct net *net, struct sock *sk, struct sk_
410425 skb -> pkt_type = PACKET_HOST ;
411426 }
412427 } else {
413- rt = bridge_parent_rtable (nf_bridge -> physindev );
428+ rt = bridge_parent_rtable (br_indev );
414429 if (!rt ) {
415430 kfree_skb (skb );
416431 return 0 ;
@@ -419,7 +434,7 @@ static int br_nf_pre_routing_finish(struct net *net, struct sock *sk, struct sk_
419434 skb_dst_set_noref (skb , & rt -> dst );
420435 }
421436
422- skb -> dev = nf_bridge -> physindev ;
437+ skb -> dev = br_indev ;
423438 nf_bridge_update_protocol (skb );
424439 nf_bridge_push_encap_header (skb );
425440 br_nf_hook_thresh (NF_BR_PRE_ROUTING , net , sk , skb , skb -> dev , NULL ,
@@ -456,7 +471,7 @@ struct net_device *setup_pre_routing(struct sk_buff *skb, const struct net *net)
456471 }
457472
458473 nf_bridge -> in_prerouting = 1 ;
459- nf_bridge -> physindev = skb -> dev ;
474+ nf_bridge -> physinif = skb -> dev -> ifindex ;
460475 skb -> dev = brnf_get_logical_dev (skb , skb -> dev , net );
461476
462477 if (skb -> protocol == htons (ETH_P_8021Q ))
@@ -553,7 +568,11 @@ static int br_nf_forward_finish(struct net *net, struct sock *sk, struct sk_buff
553568 if (skb -> protocol == htons (ETH_P_IPV6 ))
554569 nf_bridge -> frag_max_size = IP6CB (skb )-> frag_max_size ;
555570
556- in = nf_bridge -> physindev ;
571+ in = nf_bridge_get_physindev (skb , net );
572+ if (!in ) {
573+ kfree_skb (skb );
574+ return 0 ;
575+ }
557576 if (nf_bridge -> pkt_otherhost ) {
558577 skb -> pkt_type = PACKET_OTHERHOST ;
559578 nf_bridge -> pkt_otherhost = false;
@@ -899,6 +918,13 @@ static unsigned int ip_sabotage_in(void *priv,
899918static void br_nf_pre_routing_finish_bridge_slow (struct sk_buff * skb )
900919{
901920 struct nf_bridge_info * nf_bridge = nf_bridge_info_get (skb );
921+ struct net_device * br_indev ;
922+
923+ br_indev = nf_bridge_get_physindev (skb , dev_net (skb -> dev ));
924+ if (!br_indev ) {
925+ kfree_skb (skb );
926+ return ;
927+ }
902928
903929 skb_pull (skb , ETH_HLEN );
904930 nf_bridge -> bridged_dnat = 0 ;
@@ -908,7 +934,7 @@ static void br_nf_pre_routing_finish_bridge_slow(struct sk_buff *skb)
908934 skb_copy_to_linear_data_offset (skb , - (ETH_HLEN - ETH_ALEN ),
909935 nf_bridge -> neigh_header ,
910936 ETH_HLEN - ETH_ALEN );
911- skb -> dev = nf_bridge -> physindev ;
937+ skb -> dev = br_indev ;
912938
913939 nf_bridge -> physoutdev = NULL ;
914940 br_handle_frame_finish (dev_net (skb -> dev ), NULL , skb );
0 commit comments