add MACsec support
Subsystems (3)
v4 cover add MACsec support
This series introduces support for MACsec devices, with a new device type for ip link, and a new ip macsec subcommand.
The first three patches introduce some necessary helper functions.
Sabrina Dubroca (4):
utils: make hexstring_a2n provide the number of hex digits parsed
utils: add get_be{16,32,64}, use them where possible
utils: provide get_hex to read a hex digit from a char
ip: add MACsec support
include/utils.h | 8 +- ip/Makefile | 2 +- ip/ip.c | 3 +- ip/ip_common.h | 1 + ip/ipfou.c | 3 +- ip/ipl2tp.c | 15 +- ip/iplink_vxlan.c | 8 +- ip/ipmacsec.c | 1292 +++++++++++++++++++++++++++++++++++++++++++++++++ ip/iproute_lwtunnel.c | 8 +- ip/ipxfrm.c | 13 +- ip/xfrm_state.c | 10 +- lib/ipx_pton.c | 18 +- lib/ll_proto.c | 3 +- lib/utils.c | 53 +- man/man8/Makefile | 2 +- man/man8/ip-link.8.in | 85 ++++ man/man8/ip-macsec.8 | 98 ++++ tc/f_flower.c | 4 +- tc/f_u32.c | 10 +- 19 files changed, 1560 insertions(+), 76 deletions(-) create mode 100644 ip/ipmacsec.c create mode 100644 man/man8/ip-macsec.8
Signature · 1 line
2.8.3
PATCH v4 1/4 utils: make hexstring_a2n provide the number of hex digits parsed
--- include/utils.h | 4 ++-- lib/utils.c | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-)
include/utils.h +2 -2
@@ -114,8 +114,8 @@ int get_u8(__u8 *val, const char *arg, int base);int get_s8 (__s8 *val,const char *arg,int base);int get_addr64 (__u64 *ap,const char *cp); -char *hexstring_n2a (const __u8 *str,int len,char *buf,int blen); -__u8 *hexstring_a2n (const char *str,__u8 *buf,int blen); +char *hexstring_n2a (const __u8 *str,int len,char *buf,int blen); +__u8 *hexstring_a2n (const char *str,__u8 *buf,int blen,unsigned int *len);#define ADDR64_BUF_SIZE sizeof("xxxx:xxxx:xxxx:xxxx")int addr64_n2a (__u64 addr,char *buff,size_t len);
lib/utils.c +6 -2
@@ -866,9 +866,9 @@ char *hexstring_n2a(const __u8 *str, int len, char *buf, int blen)return buf; } -__u8 *hexstring_a2n (const char *str,__u8 *buf,int blen) +__u8 *hexstring_a2n (const char *str,__u8 *buf,int blen,unsigned int *len) { -int cnt =0 ; +unsigned int cnt =0 ;char *endptr;if (strlen (str) %2 )
@@ -885,6 +885,10 @@ __u8* hexstring_a2n(const char *str, __u8 *buf, int blen) buf[cnt++] = tmp; str +=2 ; } + +if (len) + *len = cnt; +return buf; }
Signature · 1 line
2.8.3
PATCH v4 2/4 utils: add get_be{16,32,64}, use them where possible
In reply to Sabrina Dubroca--- include/utils.h | 3 +++ ip/ipfou.c | 3 +-- ip/iplink_vxlan.c | 8 ++------ ip/iproute_lwtunnel.c | 8 ++++---- ip/ipxfrm.c | 13 +++---------- ip/xfrm_state.c | 10 +++------- lib/ll_proto.c | 3 +-- lib/utils.c | 33 +++++++++++++++++++++++++++++++++ tc/f_flower.c | 4 ++-- tc/f_u32.c | 10 ++-------- 10 files changed, 54 insertions(+), 41 deletions(-)
include/utils.h +3 -0
@@ -112,6 +112,9 @@ int get_u16(__u16 *val, const char *arg, int base);int get_s16 (__s16 *val,const char *arg,int base);int get_u8 (__u8 *val,const char *arg,int base);int get_s8 (__s8 *val,const char *arg,int base); +int get_be64 (__be64 *val,const char *arg,int base); +int get_be32 (__be32 *val,const char *arg,int base); +int get_be16 (__be16 *val,const char *arg,int base);int get_addr64 (__u64 *ap,const char *cp);char *hexstring_n2a (const __u8 *str,int len,char *buf,int blen);
ip/ipfou.c +1 -2
@@ -55,9 +55,8 @@ static int fou_parse_opt(int argc, char **argv, struct nlmsghdr *n,if (!matches (*argv,"port" )) {NEXT_ARG (); -if (get_u16 (&port, *argv,0 ) || port ==0 ) +if (get_be16 (&port, *argv,0 ) || port ==0 )invarg ("invalid port" , *argv); - port =htons (port); port_set =1 ; }else if (!matches (*argv,"ipproto" )) {struct protoent *servptr;
ip/iplink_vxlan.c +2 -6
@@ -172,16 +172,12 @@ static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv,invarg ("max addresses" , *argv); }else if (!matches (*argv,"port" ) || !matches (*argv,"srcport" )) { -__u16 minport, maxport; -NEXT_ARG (); -if (get_u16 (&minport, *argv,0 )) +if (get_be16 (&range.low, *argv,0 ))invarg ("min port" , *argv);NEXT_ARG (); -if (get_u16 (&maxport, *argv,0 )) +if (get_be16 (&range.high, *argv,0 ))invarg ("max port" , *argv); - range.low =htons (minport); - range.high =htons (maxport); }else if (!matches (*argv,"dstport" )) {NEXT_ARG ();if (get_u16 (&dstport, *argv,0 ))
ip/iproute_lwtunnel.c +4 -4
@@ -190,9 +190,9 @@ static int parse_encap_ip(struct rtattr *rta, size_t len, int *argcp, char ***arNEXT_ARG ();if (id_ok++)duparg2 ("id" , *argv); -if (get_u64 (&id, *argv,0 )) +if (get_be64 (&id, *argv,0 ))invarg ("\"id\" value is invalid\n" , *argv); -rta_addattr64 (rta, len,LWTUNNEL_IP_ID ,htonll (id)); +rta_addattr64 (rta, len,LWTUNNEL_IP_ID , id); }else if (strcmp (*argv,"dst" ) ==0 ) {inet_prefix addr;
@@ -267,9 +267,9 @@ static int parse_encap_ip6(struct rtattr *rta, size_t len, int *argcp, char ***aNEXT_ARG ();if (id_ok++)duparg2 ("id" , *argv); -if (get_u64 (&id, *argv,0 )) +if (get_be64 (&id, *argv,0 ))invarg ("\"id\" value is invalid\n" , *argv); -rta_addattr64 (rta, len,LWTUNNEL_IP6_ID ,htonll (id)); +rta_addattr64 (rta, len,LWTUNNEL_IP6_ID , id); }else if (strcmp (*argv,"dst" ) ==0 ) {inet_prefix addr;
ip/ipxfrm.c +3 -10
@@ -1109,15 +1109,10 @@ int xfrm_id_parse(xfrm_address_t *saddr, struct xfrm_id *id, __u16 *family, filter.id_proto_mask =XFRM_FILTER_MASK_FULL ; }else if (strcmp (*argv,"spi" ) ==0 ) { -__u32 spi; -NEXT_ARG (); -if (get_u32 (&spi, *argv,0 )) +if (get_be32 (&id->spi, *argv,0 ))invarg ("SPI value is invalid" , *argv); - spi =htonl (spi); - id->spi = spi; - filter.id_spi_mask =XFRM_FILTER_MASK_FULL ; }else {
@@ -1252,9 +1247,8 @@ static int xfrm_selector_upspec_parse(struct xfrm_selector *sel,NEXT_ARG (); -if (get_u16 (&sel->sport, *argv,0 )) +if (get_be16 (&sel->sport, *argv,0 ))invarg ("value after \"sport\" is invalid" , *argv); - sel->sport =htons (sel->sport);if (sel->sport) sel->sport_mask = ~((__u16 )0 );
@@ -1265,9 +1259,8 @@ static int xfrm_selector_upspec_parse(struct xfrm_selector *sel,NEXT_ARG (); -if (get_u16 (&sel->dport, *argv,0 )) +if (get_be16 (&sel->dport, *argv,0 ))invarg ("value after \"dport\" is invalid" , *argv); - sel->dport =htons (sel->dport);if (sel->dport) sel->dport_mask = ~((__u16 )0 );
ip/xfrm_state.c +3 -7
@@ -175,11 +175,9 @@ static int xfrm_seq_parse(__u32 *seq, int *argcp, char ***argvp)int argc = *argcp;char **argv = *argvp; -if (get_u32 (seq, *argv,0 )) +if (get_be32 (seq, *argv,0 ))invarg ("SEQ value is invalid" , *argv); - *seq =htonl (*seq); - *argcp = argc; *argvp = argv;
@@ -359,13 +357,11 @@ static int xfrm_state_modify(int cmd, unsigned int flags, int argc, char **argv)NEXT_ARG ();xfrm_encap_type_parse (&encap.encap_type, &argc, &argv);NEXT_ARG (); -if (get_u16 (&encap.encap_sport, *argv,0 )) +if (get_be16 (&encap.encap_sport, *argv,0 ))invarg ("SPORT value after \"encap\" is invalid" , *argv); - encap.encap_sport =htons (encap.encap_sport);NEXT_ARG (); -if (get_u16 (&encap.encap_dport, *argv,0 )) +if (get_be16 (&encap.encap_dport, *argv,0 ))invarg ("DPORT value after \"encap\" is invalid" , *argv); - encap.encap_dport =htons (encap.encap_dport);NEXT_ARG ();get_addr (&oa, *argv,AF_UNSPEC );memcpy (&encap.encap_oa, &oa.data,sizeof (encap.encap_oa));
lib/ll_proto.c +1 -2
@@ -111,8 +111,7 @@ int ll_proto_a2n(unsigned short *id, const char *buf)return 0 ; } } -if (get_u16 (id, buf,0 )) +if (get_be16 (id, buf,0 ))return -1 ; - *id =htons (*id);return 0 ; }
lib/utils.c +33 -0
@@ -353,6 +353,39 @@ int get_s8(__s8 *val, const char *arg, int base)return 0 ; } +int get_be64 (__be64 *val,const char *arg,int base) +{ +__u64 v; +int ret =get_u64 (&v, arg, base); + +if (!ret) + *val =htonll (v); + +return ret; +} + +int get_be32 (__be32 *val,const char *arg,int base) +{ +__u32 v; +int ret =get_u32 (&v, arg, base); + +if (!ret) + *val =htonl (v); + +return ret; +} + +int get_be16 (__be16 *val,const char *arg,int base) +{ +__u16 v; +int ret =get_u16 (&v, arg, base); + +if (!ret) + *val =htons (v); + +return ret; +} +/* This uses a non-standard parsing (ie not inet_aton, or inet_pton) * because of legacy choice to parse 10.8 as 10.8.0.0 not 10.0.0.8 */
tc/f_flower.c +2 -2
@@ -150,11 +150,11 @@ static int flower_parse_port(char *str, __u8 ip_port,return -1 ; } - ret =get_u16 (&port, str,10 ); + ret =get_be16 (&port, str,10 );if (ret)return -1 ; -addattr16 (n,MAX_MSG , type,htons (port)); +addattr16 (n,MAX_MSG , type, port);return 0 ; }
tc/f_u32.c +2 -8
@@ -767,12 +767,9 @@ static int parse_offset(int *argc_p, char ***argv_p, struct tc_u32_sel *sel) } sel->flags |=TC_U32_VAROFFSET ; }else if (matches (*argv,"mask" ) ==0 ) { -__u16 mask; -NEXT_ARG (); -if (get_u16 (&mask, *argv,16 )) +if (get_be16 (&sel->offmask, *argv,16 ))return -1 ; - sel->offmask =htons (mask); sel->flags |=TC_U32_VAROFFSET ; }else if (matches (*argv,"shift" ) ==0 ) {int shift;
@@ -802,12 +799,9 @@ static int parse_hashkey(int *argc_p, char ***argv_p, struct tc_u32_sel *sel)while (argc >0 ) {if (matches (*argv,"mask" ) ==0 ) { -__u32 mask; -NEXT_ARG (); -if (get_u32 (&mask, *argv,16 )) +if (get_be32 (&sel->hmask, *argv,16 ))return -1 ; - sel->hmask =htonl (mask); }else if (matches (*argv,"at" ) ==0 ) {int num;
Signature · 1 line
2.8.3
PATCH v4 3/4 utils: provide get_hex to read a hex digit from a char
In reply to Sabrina Dubroca--- include/utils.h | 1 + ip/ipl2tp.c | 15 ++------------- lib/ipx_pton.c | 18 +++--------------- lib/utils.c | 12 ++++++++++++ 4 files changed, 18 insertions(+), 28 deletions(-)
include/utils.h +1 -0
@@ -99,6 +99,7 @@ int get_prefix(inet_prefix *dst, char *arg, int family);int mask2bits (__u32 netmask);int get_addr_ila (__u64 *val,const char *arg); +int get_hex (char c);int get_integer (int *val,const char *arg,int base);int get_unsigned (unsigned *val,const char *arg,int base);int get_time_rtt (unsigned *val,const char *arg,int *raw);
ip/ipl2tp.c +2 -13
@@ -425,30 +425,19 @@ static int get_tunnel(struct l2tp_data *p)* Command parser *****************************************************************************/ -static int hex (char ch) -{ -if ((ch >='a' ) && (ch <='f' )) -return ch -'a' +10 ; -if ((ch >='0' ) && (ch <='9' )) -return ch -'0' ; -if ((ch >='A' ) && (ch <='F' )) -return ch -'A' +10 ; -return -1 ; -} -static int hex2mem (const char *buf,uint8_t *mem,int count) {int i, j;int c;for (i =0 , j =0 ; i < count; i++, j +=2 ) { - c =hex (buf[j]); + c =get_hex (buf[j]);if (c <0 ) goto err; mem[i] = c <<4 ; - c =hex (buf[j +1 ]); + c =get_hex (buf[j +1 ]);if (c <0 ) goto err;
lib/ipx_pton.c +3 -15
@@ -6,18 +6,6 @@#include "utils.h" -static u_int32_t hexget (char c) -{ -if (c >='A' && c <='F' ) -return c -'A' +10 ; -if (c >='a' && c <='f' ) -return c -'a' +10 ; -if (c >='0' && c <='9' ) -return c -'0' ; - -return 0xf0 ; -} -static int ipx_getnet (u_int32_t *net,const char *str) {int i;
@@ -25,7 +13,7 @@ static int ipx_getnet(u_int32_t *net, const char *str)for (i =0 ; *str && (i <8 ); i++) { -if ((tmp =hexget (*str)) &0xf0 ) { +if ((tmp =get_hex (*str)) ==-1 ) {if (*str =='.' )return 0 ;else
@@ -49,11 +37,11 @@ static int ipx_getnode(u_int8_t *node, const char *str)u_int32_t tmp;for (i =0 ; i <6 ; i++) { -if ((tmp =hexget (*str++)) &0xf0 ) +if ((tmp =get_hex (*str++)) ==-1 )return -1 ; node[i] = (u_int8_t )tmp; node[i] <<=4 ; -if ((tmp =hexget (*str++)) &0xf0 ) +if ((tmp =get_hex (*str++)) ==-1 )return -1 ; node[i] |= (u_int8_t )tmp;if (*str ==':' )
lib/utils.c +12 -0
@@ -37,6 +37,18 @@int timestamp_short =0 ; +int get_hex (char c) +{ +if (c >='A' && c <='F' ) +return c -'A' +10 ; +if (c >='a' && c <='f' ) +return c -'a' +10 ; +if (c >='0' && c <='9' ) +return c -'0' ; + +return -1 ; +} +int get_integer (int *val,const char *arg,int base) {long res;
Signature · 1 line
2.8.3
PATCH v4 4/4 ip: add MACsec support
In reply to Sabrina DubrocaExtend ip-link to create MACsec devices
ip link add link <master> <macsec> type macsec [options]
Add ip macsec command to configure receive-side secure channels and secure associations within a macsec netdevice.
---
Changes since v1:
- use new utils
- adapt to new netlink API
- clean up stats printing
- make commands and output symmetrical
Changes since v2:
- modified uAPI
- cleaned up some unused struct fields
- manpage syntax cleanup from Phil Sutter
Changes since v3:
- reformat lines over 80 chars
- swap values in values_on_off so that on <-> true
- fix handling of stats message vs _PAD attribute
--- ip/Makefile | 2 +- ip/ip.c | 3 +- ip/ip_common.h | 1 + ip/ipmacsec.c | 1292 +++++++++++++++++++++++++++++++++++++++++++++++++ man/man8/Makefile | 2 +- man/man8/ip-link.8.in | 85 ++++ man/man8/ip-macsec.8 | 98 ++++ 7 files changed, 1480 insertions(+), 3 deletions(-) create mode 100644 ip/ipmacsec.c create mode 100644 man/man8/ip-macsec.8
ip/Makefile +1 -1
@@ -7,7 +7,7 @@ IPOBJ=ip.o ipaddress.o ipaddrlabel.o iproute.o iprule.o ipnetns.o \ iplink_vxlan.o tcp_metrics.o iplink_ipoib.o ipnetconf.o link_ip6tnl.o \ link_iptnl.o link_gre6.o iplink_bond.o iplink_bond_slave.o iplink_hsr.o \ iplink_bridge.o iplink_bridge_slave.o ipfou.o iplink_ipvlan.o \ - iplink_geneve.o iplink_vrf.o iproute_lwtunnel.o + iplink_geneve.o iplink_vrf.o iproute_lwtunnel.o ipmacsec.o RTMONOBJ=rtmon.o
ip/ip.c +2 -1
@@ -51,7 +51,7 @@ static void usage(void)" ip [ -force ] -batch filename\n" "where OBJECT := { link | address | addrlabel | route | rule | neigh | ntable |\n" " tunnel | tuntap | maddress | mroute | mrule | monitor | xfrm |\n" -" netns | l2tp | fou | tcp_metrics | token | netconf }\n" +" netns | l2tp | fou | macsec | tcp_metrics | token | netconf }\n" " OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] |\n" " -h[uman-readable] | -iec |\n" " -f[amily] { inet | inet6 | ipx | dnet | mpls | bridge | link } |\n"
@@ -84,6 +84,7 @@ static const struct cmd { { "link", do_iplink }, { "l2tp", do_ipl2tp }, { "fou", do_ipfou }, + { "macsec", do_ipmacsec }, { "tunnel", do_iptunnel }, { "tunl", do_iptunnel }, { "tuntap", do_iptuntap },
ip/ip_common.h +1 -0
@@ -43,6 +43,7 @@ int do_iptunnel(int argc, char **argv);int do_ip6tunnel (int argc,char **argv);int do_iptuntap (int argc,char **argv);int do_iplink (int argc,char **argv); +int do_ipmacsec (int argc,char **argv);int do_ipmonitor (int argc,char **argv);int do_multiaddr (int argc,char **argv);int do_multiroute (int argc,char **argv);
ip/ipmacsec.c new file +1292 -0
1,292 lines not on this page · raw message
man/man8/Makefile +1 -1
@@ -7,7 +7,7 @@ MAN8PAGES = $(TARGETS) ip.8 arpd.8 lnstat.8 routel.8 rtacct.8 rtmon.8 rtpr.8 ss. tc-mqprio.8 tc-netem.8 tc-pfifo.8 tc-pfifo_fast.8 tc-prio.8 tc-red.8 \ tc-sfb.8 tc-sfq.8 tc-stab.8 tc-tbf.8 \ bridge.8 rtstat.8 ctstat.8 nstat.8 routef.8 \ - ip-addrlabel.8 ip-fou.8 ip-gue.8 ip-l2tp.8 \ + ip-addrlabel.8 ip-fou.8 ip-gue.8 ip-l2tp.8 ip-macsec.8 \ ip-maddress.8 ip-monitor.8 ip-mroute.8 ip-neighbour.8 \ ip-netns.8 ip-ntable.8 ip-rule.8 ip-tunnel.8 ip-xfrm.8 \ ip-tcp_metrics.8 ip-netconf.8 ip-token.8 \
man/man8/ip-link.8.in +85 -0
97 lines not on this page · raw message
man/man8/ip-macsec.8 new file +98 -0
98 lines not on this page · raw message
Signature · 1 line
2.8.3
Stephen Hemminger
AppliedRe: [PATCH iproute2 v4 4/4] ip: add MACsec support
Quoted 9 lines · On Fri, 3 Jun 2016 16:45:48 +0200 Sabrina Dubroca <[email protected]> wrote:
Extend ip-link to create MACsec devices
ip link add link <master> <macsec> type macsec [options]
Add
ip macseccommand to configure receive-side secure channels and secure associations within a macsec netdevice.Signed-off-by Sabrina Dubroca <[email protected]>Acked-by Phil Sutter <[email protected]>
Applied.