Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: Introduce ife encapsulation module

This module is responsible for the ife encapsulation protocol
encode/decode logics. That module can:
- ife_encode: encode skb and reserve space for the ife meta header
- ife_decode: decode skb and extract the meta header size
- ife_tlv_meta_encode - encodes one tlv entry into the reserved ife
header space.
- ife_tlv_meta_decode - decodes one tlv entry from the packet
- ife_tlv_meta_next - advance to the next tlv

Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Yotam Gigi <yotamg@mellanox.com>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: Roman Mashak <mrv@mojatatu.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Yotam Gigi and committed by
David S. Miller
1ce84604 1d5e7c85

+242
+7
MAINTAINERS
··· 6250 6250 F: include/net/ieee802154_netdev.h 6251 6251 F: Documentation/networking/ieee802154.txt 6252 6252 6253 + IFE PROTOCOL 6254 + M: Yotam Gigi <yotamg@mellanox.com> 6255 + M: Jamal Hadi Salim <jhs@mojatatu.com> 6256 + F: net/ife 6257 + F: include/net/ife.h 6258 + F: include/uapi/linux/ife.h 6259 + 6253 6260 IGORPLUG-USB IR RECEIVER 6254 6261 M: Sean Young <sean@mess.org> 6255 6262 L: linux-media@vger.kernel.org
+51
include/net/ife.h
··· 1 + #ifndef __NET_IFE_H 2 + #define __NET_IFE_H 3 + 4 + #include <linux/etherdevice.h> 5 + #include <linux/rtnetlink.h> 6 + #include <linux/module.h> 7 + #include <uapi/linux/ife.h> 8 + 9 + #if IS_ENABLED(CONFIG_NET_IFE) 10 + 11 + void *ife_encode(struct sk_buff *skb, u16 metalen); 12 + void *ife_decode(struct sk_buff *skb, u16 *metalen); 13 + 14 + void *ife_tlv_meta_decode(void *skbdata, u16 *attrtype, u16 *dlen, u16 *totlen); 15 + int ife_tlv_meta_encode(void *skbdata, u16 attrtype, u16 dlen, 16 + const void *dval); 17 + 18 + void *ife_tlv_meta_next(void *skbdata); 19 + 20 + #else 21 + 22 + static inline void *ife_encode(struct sk_buff *skb, u16 metalen) 23 + { 24 + return NULL; 25 + } 26 + 27 + static inline void *ife_decode(struct sk_buff *skb, u16 *metalen) 28 + { 29 + return NULL; 30 + } 31 + 32 + static inline void *ife_tlv_meta_decode(void *skbdata, u16 *attrtype, u16 *dlen, 33 + u16 *totlen) 34 + { 35 + return NULL; 36 + } 37 + 38 + static inline int ife_tlv_meta_encode(void *skbdata, u16 attrtype, u16 dlen, 39 + const void *dval) 40 + { 41 + return 0; 42 + } 43 + 44 + static inline void *ife_tlv_meta_next(void *skbdata) 45 + { 46 + return NULL; 47 + } 48 + 49 + #endif 50 + 51 + #endif /* __NET_IFE_H */
+1
include/uapi/linux/Kbuild
··· 195 195 header-y += if_tunnel.h 196 196 header-y += if_vlan.h 197 197 header-y += if_x25.h 198 + header-y += ife.h 198 199 header-y += igmp.h 199 200 header-y += ila.h 200 201 header-y += in6.h
+18
include/uapi/linux/ife.h
··· 1 + #ifndef __UAPI_IFE_H 2 + #define __UAPI_IFE_H 3 + 4 + #define IFE_METAHDRLEN 2 5 + 6 + enum { 7 + IFE_META_SKBMARK = 1, 8 + IFE_META_HASHID, 9 + IFE_META_PRIO, 10 + IFE_META_QMAP, 11 + IFE_META_TCINDEX, 12 + __IFE_META_MAX 13 + }; 14 + 15 + /*Can be overridden at runtime by module option*/ 16 + #define IFE_META_MAX (__IFE_META_MAX - 1) 17 + 18 + #endif
+1
net/Kconfig
··· 391 391 source "net/ceph/Kconfig" 392 392 source "net/nfc/Kconfig" 393 393 source "net/psample/Kconfig" 394 + source "net/ife/Kconfig" 394 395 395 396 config LWTUNNEL 396 397 bool "Network light weight tunnels"
+1
net/Makefile
··· 71 71 obj-$(CONFIG_BATMAN_ADV) += batman-adv/ 72 72 obj-$(CONFIG_NFC) += nfc/ 73 73 obj-$(CONFIG_PSAMPLE) += psample/ 74 + obj-$(CONFIG_NET_IFE) += ife/ 74 75 obj-$(CONFIG_OPENVSWITCH) += openvswitch/ 75 76 obj-$(CONFIG_VSOCKETS) += vmw_vsock/ 76 77 obj-$(CONFIG_MPLS) += mpls/
+16
net/ife/Kconfig
··· 1 + # 2 + # IFE subsystem configuration 3 + # 4 + 5 + menuconfig NET_IFE 6 + depends on NET 7 + tristate "Inter-FE based on IETF ForCES InterFE LFB" 8 + default n 9 + help 10 + Say Y here to add support of IFE encapsulation protocol 11 + For details refer to netdev01 paper: 12 + "Distributing Linux Traffic Control Classifier-Action Subsystem" 13 + Authors: Jamal Hadi Salim and Damascene M. Joachimpillai 14 + 15 + To compile this support as a module, choose M here: the module will 16 + be called ife.
+5
net/ife/Makefile
··· 1 + # 2 + # Makefile for the IFE encapsulation protocol 3 + # 4 + 5 + obj-$(CONFIG_NET_IFE) += ife.o
+142
net/ife/ife.c
··· 1 + /* 2 + * net/ife/ife.c - Inter-FE protocol based on ForCES WG InterFE LFB 3 + * Copyright (c) 2015 Jamal Hadi Salim <jhs@mojatatu.com> 4 + * Copyright (c) 2017 Yotam Gigi <yotamg@mellanox.com> 5 + * 6 + * Refer to: draft-ietf-forces-interfelfb-03 and netdev01 paper: 7 + * "Distributing Linux Traffic Control Classifier-Action Subsystem" 8 + * Authors: Jamal Hadi Salim and Damascene M. Joachimpillai 9 + * 10 + * This program is free software; you can redistribute it and/or modify 11 + * it under the terms of the GNU General Public License as published by 12 + * the Free Software Foundation. 13 + */ 14 + 15 + #include <linux/types.h> 16 + #include <linux/kernel.h> 17 + #include <linux/string.h> 18 + #include <linux/errno.h> 19 + #include <linux/skbuff.h> 20 + #include <linux/rtnetlink.h> 21 + #include <linux/module.h> 22 + #include <linux/init.h> 23 + #include <net/net_namespace.h> 24 + #include <net/netlink.h> 25 + #include <net/pkt_sched.h> 26 + #include <linux/etherdevice.h> 27 + #include <net/ife.h> 28 + 29 + struct ifeheadr { 30 + __be16 metalen; 31 + u8 tlv_data[]; 32 + }; 33 + 34 + void *ife_encode(struct sk_buff *skb, u16 metalen) 35 + { 36 + /* OUTERHDR:TOTMETALEN:{TLVHDR:Metadatum:TLVHDR..}:ORIGDATA 37 + * where ORIGDATA = original ethernet header ... 38 + */ 39 + int hdrm = metalen + IFE_METAHDRLEN; 40 + int total_push = hdrm + skb->dev->hard_header_len; 41 + struct ifeheadr *ifehdr; 42 + struct ethhdr *iethh; /* inner ether header */ 43 + int skboff = 0; 44 + int err; 45 + 46 + err = skb_cow_head(skb, total_push); 47 + if (unlikely(err)) 48 + return NULL; 49 + 50 + iethh = (struct ethhdr *) skb->data; 51 + 52 + __skb_push(skb, total_push); 53 + memcpy(skb->data, iethh, skb->dev->hard_header_len); 54 + skb_reset_mac_header(skb); 55 + skboff += skb->dev->hard_header_len; 56 + 57 + /* total metadata length */ 58 + ifehdr = (struct ifeheadr *) (skb->data + skboff); 59 + metalen += IFE_METAHDRLEN; 60 + ifehdr->metalen = htons(metalen); 61 + 62 + return ifehdr->tlv_data; 63 + } 64 + EXPORT_SYMBOL_GPL(ife_encode); 65 + 66 + void *ife_decode(struct sk_buff *skb, u16 *metalen) 67 + { 68 + struct ifeheadr *ifehdr; 69 + int total_pull; 70 + u16 ifehdrln; 71 + 72 + ifehdr = (struct ifeheadr *) (skb->data + skb->dev->hard_header_len); 73 + ifehdrln = ntohs(ifehdr->metalen); 74 + total_pull = skb->dev->hard_header_len + ifehdrln; 75 + 76 + if (unlikely(ifehdrln < 2)) 77 + return NULL; 78 + 79 + if (unlikely(!pskb_may_pull(skb, total_pull))) 80 + return NULL; 81 + 82 + skb_set_mac_header(skb, total_pull); 83 + __skb_pull(skb, total_pull); 84 + *metalen = ifehdrln - IFE_METAHDRLEN; 85 + 86 + return &ifehdr->tlv_data; 87 + } 88 + EXPORT_SYMBOL_GPL(ife_decode); 89 + 90 + struct meta_tlvhdr { 91 + __be16 type; 92 + __be16 len; 93 + }; 94 + 95 + /* Caller takes care of presenting data in network order 96 + */ 97 + void *ife_tlv_meta_decode(void *skbdata, u16 *attrtype, u16 *dlen, u16 *totlen) 98 + { 99 + struct meta_tlvhdr *tlv = (struct meta_tlvhdr *) skbdata; 100 + 101 + *dlen = ntohs(tlv->len) - NLA_HDRLEN; 102 + *attrtype = ntohs(tlv->type); 103 + 104 + if (totlen) 105 + *totlen = nla_total_size(*dlen); 106 + 107 + return skbdata + sizeof(struct meta_tlvhdr); 108 + } 109 + EXPORT_SYMBOL_GPL(ife_tlv_meta_decode); 110 + 111 + void *ife_tlv_meta_next(void *skbdata) 112 + { 113 + struct meta_tlvhdr *tlv = (struct meta_tlvhdr *) skbdata; 114 + u16 tlvlen = ntohs(tlv->len); 115 + 116 + tlvlen = NLA_ALIGN(tlvlen); 117 + 118 + return skbdata + tlvlen; 119 + } 120 + EXPORT_SYMBOL_GPL(ife_tlv_meta_next); 121 + 122 + /* Caller takes care of presenting data in network order 123 + */ 124 + int ife_tlv_meta_encode(void *skbdata, u16 attrtype, u16 dlen, const void *dval) 125 + { 126 + __be32 *tlv = (__be32 *) (skbdata); 127 + u16 totlen = nla_total_size(dlen); /*alignment + hdr */ 128 + char *dptr = (char *) tlv + NLA_HDRLEN; 129 + u32 htlv = attrtype << 16 | (dlen + NLA_HDRLEN); 130 + 131 + *tlv = htonl(htlv); 132 + memset(dptr, 0, totlen - NLA_HDRLEN); 133 + memcpy(dptr, dval, dlen); 134 + 135 + return totlen; 136 + } 137 + EXPORT_SYMBOL_GPL(ife_tlv_meta_encode); 138 + 139 + MODULE_AUTHOR("Jamal Hadi Salim <jhs@mojatatu.com>"); 140 + MODULE_AUTHOR("Yotam Gigi <yotamg@mellanox.com>"); 141 + MODULE_DESCRIPTION("Inter-FE LFB action"); 142 + MODULE_LICENSE("GPL");