32
32
#include <uapi/linux/tc_act/tc_ife.h>
33
33
#include <net/tc_act/tc_ife.h>
34
34
#include <linux/etherdevice.h>
35
+ #include <net/ife.h>
35
36
36
37
#define IFE_TAB_MASK 15
37
38
@@ -46,23 +47,6 @@ static const struct nla_policy ife_policy[TCA_IFE_MAX + 1] = {
46
47
[TCA_IFE_TYPE ] = { .type = NLA_U16 },
47
48
};
48
49
49
- /* Caller takes care of presenting data in network order
50
- */
51
- static int ife_tlv_meta_encode (void * skbdata , u16 attrtype , u16 dlen ,
52
- const void * dval )
53
- {
54
- u32 * tlv = (u32 * )(skbdata );
55
- u16 totlen = nla_total_size (dlen ); /*alignment + hdr */
56
- char * dptr = (char * )tlv + NLA_HDRLEN ;
57
- u32 htlv = attrtype << 16 | (dlen + NLA_HDRLEN );
58
-
59
- * tlv = htonl (htlv );
60
- memset (dptr , 0 , totlen - NLA_HDRLEN );
61
- memcpy (dptr , dval , dlen );
62
-
63
- return totlen ;
64
- }
65
-
66
50
int ife_encode_meta_u16 (u16 metaval , void * skbdata , struct tcf_meta_info * mi )
67
51
{
68
52
u16 edata = 0 ;
@@ -637,69 +621,59 @@ int find_decode_metaid(struct sk_buff *skb, struct tcf_ife_info *ife,
637
621
return 0 ;
638
622
}
639
623
640
- struct ifeheadr {
641
- __be16 metalen ;
642
- u8 tlv_data [];
643
- };
644
-
645
- struct meta_tlvhdr {
646
- __be16 type ;
647
- __be16 len ;
648
- };
649
-
650
624
static int tcf_ife_decode (struct sk_buff * skb , const struct tc_action * a ,
651
625
struct tcf_result * res )
652
626
{
653
627
struct tcf_ife_info * ife = to_ife (a );
654
628
int action = ife -> tcf_action ;
655
- struct ifeheadr * ifehdr = ( struct ifeheadr * ) skb -> data ;
656
- int ifehdrln = ( int ) ifehdr -> metalen ;
657
- struct meta_tlvhdr * tlv = ( struct meta_tlvhdr * )( ifehdr -> tlv_data ) ;
629
+ u8 * ifehdr_end ;
630
+ u8 * tlv_data ;
631
+ u16 metalen ;
658
632
659
633
spin_lock (& ife -> tcf_lock );
660
634
bstats_update (& ife -> tcf_bstats , skb );
661
635
tcf_lastuse_update (& ife -> tcf_tm );
662
636
spin_unlock (& ife -> tcf_lock );
663
637
664
- ifehdrln = ntohs (ifehdrln );
665
- if (unlikely (!pskb_may_pull (skb , ifehdrln ))) {
638
+ if (skb_at_tc_ingress (skb ))
639
+ skb_push (skb , skb -> dev -> hard_header_len );
640
+
641
+ tlv_data = ife_decode (skb , & metalen );
642
+ if (unlikely (!tlv_data )) {
666
643
spin_lock (& ife -> tcf_lock );
667
644
ife -> tcf_qstats .drops ++ ;
668
645
spin_unlock (& ife -> tcf_lock );
669
646
return TC_ACT_SHOT ;
670
647
}
671
648
672
- skb_set_mac_header (skb , ifehdrln );
673
- __skb_pull (skb , ifehdrln );
674
- skb -> protocol = eth_type_trans (skb , skb -> dev );
675
- ifehdrln -= IFE_METAHDRLEN ;
676
-
677
- while (ifehdrln > 0 ) {
678
- u8 * tlvdata = (u8 * )tlv ;
679
- u16 mtype = tlv -> type ;
680
- u16 mlen = tlv -> len ;
681
- u16 alen ;
649
+ ifehdr_end = tlv_data + metalen ;
650
+ for (; tlv_data < ifehdr_end ; tlv_data = ife_tlv_meta_next (tlv_data )) {
651
+ u8 * curr_data ;
652
+ u16 mtype ;
653
+ u16 dlen ;
682
654
683
- mtype = ntohs (mtype );
684
- mlen = ntohs (mlen );
685
- alen = NLA_ALIGN (mlen );
655
+ curr_data = ife_tlv_meta_decode (tlv_data , & mtype , & dlen , NULL );
686
656
687
- if (find_decode_metaid (skb , ife , mtype , (mlen - NLA_HDRLEN ),
688
- (void * )(tlvdata + NLA_HDRLEN ))) {
657
+ if (find_decode_metaid (skb , ife , mtype , dlen , curr_data )) {
689
658
/* abuse overlimits to count when we receive metadata
690
659
* but dont have an ops for it
691
660
*/
692
- pr_info_ratelimited ("Unknown metaid %d alnlen %d\n" ,
693
- mtype , mlen );
661
+ pr_info_ratelimited ("Unknown metaid %d dlen %d\n" ,
662
+ mtype , dlen );
694
663
ife -> tcf_qstats .overlimits ++ ;
695
664
}
665
+ }
696
666
697
- tlvdata += alen ;
698
- ifehdrln -= alen ;
699
- tlv = (struct meta_tlvhdr * )tlvdata ;
667
+ if (WARN_ON (tlv_data != ifehdr_end )) {
668
+ spin_lock (& ife -> tcf_lock );
669
+ ife -> tcf_qstats .drops ++ ;
670
+ spin_unlock (& ife -> tcf_lock );
671
+ return TC_ACT_SHOT ;
700
672
}
701
673
674
+ skb -> protocol = eth_type_trans (skb , skb -> dev );
702
675
skb_reset_network_header (skb );
676
+
703
677
return action ;
704
678
}
705
679
@@ -727,18 +701,18 @@ static int tcf_ife_encode(struct sk_buff *skb, const struct tc_action *a,
727
701
struct tcf_ife_info * ife = to_ife (a );
728
702
int action = ife -> tcf_action ;
729
703
struct ethhdr * oethh ; /* outer ether header */
730
- struct ethhdr * iethh ; /* inner eth header */
731
704
struct tcf_meta_info * e ;
732
705
/*
733
706
OUTERHDR:TOTMETALEN:{TLVHDR:Metadatum:TLVHDR..}:ORIGDATA
734
707
where ORIGDATA = original ethernet header ...
735
708
*/
736
709
u16 metalen = ife_get_sz (skb , ife );
737
710
int hdrm = metalen + skb -> dev -> hard_header_len + IFE_METAHDRLEN ;
738
- unsigned int skboff = skb -> dev -> hard_header_len ;
711
+ unsigned int skboff = 0 ;
739
712
int new_len = skb -> len + hdrm ;
740
713
bool exceed_mtu = false;
741
- int err ;
714
+ void * ife_meta ;
715
+ int err = 0 ;
742
716
743
717
if (!skb_at_tc_ingress (skb )) {
744
718
if (new_len > skb -> dev -> mtu )
@@ -765,35 +739,18 @@ static int tcf_ife_encode(struct sk_buff *skb, const struct tc_action *a,
765
739
return TC_ACT_SHOT ;
766
740
}
767
741
768
- err = skb_cow_head (skb , hdrm );
769
- if (unlikely (err )) {
770
- ife -> tcf_qstats .drops ++ ;
771
- spin_unlock (& ife -> tcf_lock );
772
- return TC_ACT_SHOT ;
773
- }
774
-
775
742
if (skb_at_tc_ingress (skb ))
776
743
skb_push (skb , skb -> dev -> hard_header_len );
777
744
778
- iethh = (struct ethhdr * )skb -> data ;
779
- __skb_push (skb , hdrm );
780
- memcpy (skb -> data , iethh , skb -> mac_len );
781
- skb_reset_mac_header (skb );
782
- oethh = eth_hdr (skb );
783
-
784
- /*total metadata length */
785
- metalen += IFE_METAHDRLEN ;
786
- metalen = htons (metalen );
787
- memcpy ((skb -> data + skboff ), & metalen , IFE_METAHDRLEN );
788
- skboff += IFE_METAHDRLEN ;
745
+ ife_meta = ife_encode (skb , metalen );
789
746
790
747
/* XXX: we dont have a clever way of telling encode to
791
748
* not repeat some of the computations that are done by
792
749
* ops->presence_check...
793
750
*/
794
751
list_for_each_entry (e , & ife -> metalist , metalist ) {
795
752
if (e -> ops -> encode ) {
796
- err = e -> ops -> encode (skb , (void * )(skb -> data + skboff ),
753
+ err = e -> ops -> encode (skb , (void * )(ife_meta + skboff ),
797
754
e );
798
755
}
799
756
if (err < 0 ) {
@@ -804,15 +761,12 @@ static int tcf_ife_encode(struct sk_buff *skb, const struct tc_action *a,
804
761
}
805
762
skboff += err ;
806
763
}
764
+ oethh = (struct ethhdr * )skb -> data ;
807
765
808
766
if (!is_zero_ether_addr (ife -> eth_src ))
809
767
ether_addr_copy (oethh -> h_source , ife -> eth_src );
810
- else
811
- ether_addr_copy (oethh -> h_source , iethh -> h_source );
812
768
if (!is_zero_ether_addr (ife -> eth_dst ))
813
769
ether_addr_copy (oethh -> h_dest , ife -> eth_dst );
814
- else
815
- ether_addr_copy (oethh -> h_dest , iethh -> h_dest );
816
770
oethh -> h_proto = htons (ife -> eth_type );
817
771
818
772
if (skb_at_tc_ingress (skb ))
0 commit comments