add MACsec support
Subsystems (3)
v3 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 patch imports the if_macsec.h header from kernel uapi.
The next three patches introduce some necessary helper functions.
Sabrina Dubroca (5):
add missing if_macsec.h header from kernel
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/linux/if_macsec.h | 163 ++++++ 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 | 1236 +++++++++++++++++++++++++++++++++++++++++++++ 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 +- 20 files changed, 1667 insertions(+), 76 deletions(-) create mode 100644 include/linux/if_macsec.h create mode 100644 ip/ipmacsec.c create mode 100644 man/man8/ip-macsec.8
Signature · 1 line
2.8.2
PATCH v3 1/5 add missing if_macsec.h header from kernel
--- include/linux/if_macsec.h | 163 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 include/linux/if_macsec.h
include/linux/if_macsec.h new file +163 -0
@@ -0,0 +1,163 @@ +/* +* include/uapi/linux/if_macsec.h - MACsec device +* +* Copyright (c) 2015 Sabrina Dubroca <[email protected]> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +*/ + +#ifndef _MACSEC_H +#define _MACSEC_H + +#include <linux/types.h> + +#define MACSEC_GENL_NAME "macsec" +#define MACSEC_GENL_VERSION 1 + +#define MACSEC_MAX_KEY_LEN 128 + +#define MACSEC_KEYID_LEN 16 + +#define MACSEC_DEFAULT_CIPHER_ID 0x0080020001000001ULL +#define MACSEC_DEFAULT_CIPHER_ALT 0x0080C20001000001ULL + +#define MACSEC_MIN_ICV_LEN 8 +#define MACSEC_MAX_ICV_LEN 32 + +enum macsec_attrs { +MACSEC_ATTR_UNSPEC , +MACSEC_ATTR_IFINDEX ,/* u32, ifindex of the MACsec netdevice */ +MACSEC_ATTR_RXSC_CONFIG ,/* config, nested macsec_rxsc_attrs */ +MACSEC_ATTR_SA_CONFIG ,/* config, nested macsec_sa_attrs */ +MACSEC_ATTR_SECY ,/* dump, nested macsec_secy_attrs */ +MACSEC_ATTR_TXSA_LIST ,/* dump, nested, macsec_sa_attrs for each TXSA */ +MACSEC_ATTR_RXSC_LIST ,/* dump, nested, macsec_rxsc_attrs for each RXSC */ +MACSEC_ATTR_TXSC_STATS ,/* dump, nested, macsec_txsc_stats_attr */ +MACSEC_ATTR_SECY_STATS ,/* dump, nested, macsec_secy_stats_attr */ + __MACSEC_ATTR_END, +NUM_MACSEC_ATTR = __MACSEC_ATTR_END, +MACSEC_ATTR_MAX = __MACSEC_ATTR_END -1 , +}; + +enum macsec_secy_attrs { +MACSEC_SECY_ATTR_UNSPEC , +MACSEC_SECY_ATTR_SCI , +MACSEC_SECY_ATTR_ENCODING_SA , +MACSEC_SECY_ATTR_WINDOW , +MACSEC_SECY_ATTR_CIPHER_SUITE , +MACSEC_SECY_ATTR_ICV_LEN , +MACSEC_SECY_ATTR_PROTECT , +MACSEC_SECY_ATTR_REPLAY , +MACSEC_SECY_ATTR_OPER , +MACSEC_SECY_ATTR_VALIDATE , +MACSEC_SECY_ATTR_ENCRYPT , +MACSEC_SECY_ATTR_INC_SCI , +MACSEC_SECY_ATTR_ES , +MACSEC_SECY_ATTR_SCB , + __MACSEC_SECY_ATTR_END, +NUM_MACSEC_SECY_ATTR = __MACSEC_SECY_ATTR_END, +MACSEC_SECY_ATTR_MAX = __MACSEC_SECY_ATTR_END -1 , +}; + +enum macsec_rxsc_attrs { +MACSEC_RXSC_ATTR_UNSPEC , +MACSEC_RXSC_ATTR_SCI ,/* config/dump, u64 */ +MACSEC_RXSC_ATTR_ACTIVE ,/* config/dump, u8 0..1 */ +MACSEC_RXSC_ATTR_SA_LIST ,/* dump, nested */ +MACSEC_RXSC_ATTR_STATS ,/* dump, nested, macsec_rxsc_stats_attr */ + __MACSEC_RXSC_ATTR_END, +NUM_MACSEC_RXSC_ATTR = __MACSEC_RXSC_ATTR_END, +MACSEC_RXSC_ATTR_MAX = __MACSEC_RXSC_ATTR_END -1 , +}; + +enum macsec_sa_attrs { +MACSEC_SA_ATTR_UNSPEC , +MACSEC_SA_ATTR_AN ,/* config/dump, u8 0..3 */ +MACSEC_SA_ATTR_ACTIVE ,/* config/dump, u8 0..1 */ +MACSEC_SA_ATTR_PN ,/* config/dump, u32 */ +MACSEC_SA_ATTR_KEY ,/* config, data */ +MACSEC_SA_ATTR_KEYID ,/* config/dump, 128-bit */ +MACSEC_SA_ATTR_STATS ,/* dump, nested, macsec_sa_stats_attr */ + __MACSEC_SA_ATTR_END, +NUM_MACSEC_SA_ATTR = __MACSEC_SA_ATTR_END, +MACSEC_SA_ATTR_MAX = __MACSEC_SA_ATTR_END -1 , +}; + +enum macsec_nl_commands { +MACSEC_CMD_GET_TXSC , +MACSEC_CMD_ADD_RXSC , +MACSEC_CMD_DEL_RXSC , +MACSEC_CMD_UPD_RXSC , +MACSEC_CMD_ADD_TXSA , +MACSEC_CMD_DEL_TXSA , +MACSEC_CMD_UPD_TXSA , +MACSEC_CMD_ADD_RXSA , +MACSEC_CMD_DEL_RXSA , +MACSEC_CMD_UPD_RXSA , +}; + +/* u64 per-RXSC stats */ +enum macsec_rxsc_stats_attr { +MACSEC_RXSC_STATS_ATTR_UNSPEC , +MACSEC_RXSC_STATS_ATTR_IN_OCTETS_VALIDATED , +MACSEC_RXSC_STATS_ATTR_IN_OCTETS_DECRYPTED , +MACSEC_RXSC_STATS_ATTR_IN_PKTS_UNCHECKED , +MACSEC_RXSC_STATS_ATTR_IN_PKTS_DELAYED , +MACSEC_RXSC_STATS_ATTR_IN_PKTS_OK , +MACSEC_RXSC_STATS_ATTR_IN_PKTS_INVALID , +MACSEC_RXSC_STATS_ATTR_IN_PKTS_LATE , +MACSEC_RXSC_STATS_ATTR_IN_PKTS_NOT_VALID , +MACSEC_RXSC_STATS_ATTR_IN_PKTS_NOT_USING_SA , +MACSEC_RXSC_STATS_ATTR_IN_PKTS_UNUSED_SA , + __MACSEC_RXSC_STATS_ATTR_END, +NUM_MACSEC_RXSC_STATS_ATTR = __MACSEC_RXSC_STATS_ATTR_END, +MACSEC_RXSC_STATS_ATTR_MAX = __MACSEC_RXSC_STATS_ATTR_END -1 , +}; + +/* u32 per-{RX,TX}SA stats */ +enum macsec_sa_stats_attr { +MACSEC_SA_STATS_ATTR_UNSPEC , +MACSEC_SA_STATS_ATTR_IN_PKTS_OK , +MACSEC_SA_STATS_ATTR_IN_PKTS_INVALID , +MACSEC_SA_STATS_ATTR_IN_PKTS_NOT_VALID , +MACSEC_SA_STATS_ATTR_IN_PKTS_NOT_USING_SA , +MACSEC_SA_STATS_ATTR_IN_PKTS_UNUSED_SA , +MACSEC_SA_STATS_ATTR_OUT_PKTS_PROTECTED , +MACSEC_SA_STATS_ATTR_OUT_PKTS_ENCRYPTED , + __MACSEC_SA_STATS_ATTR_END, +NUM_MACSEC_SA_STATS_ATTR = __MACSEC_SA_STATS_ATTR_END, +MACSEC_SA_STATS_ATTR_MAX = __MACSEC_SA_STATS_ATTR_END -1 , +}; + +/* u64 per-TXSC stats */ +enum macsec_txsc_stats_attr { +MACSEC_TXSC_STATS_ATTR_UNSPEC , +MACSEC_TXSC_STATS_ATTR_OUT_PKTS_PROTECTED , +MACSEC_TXSC_STATS_ATTR_OUT_PKTS_ENCRYPTED , +MACSEC_TXSC_STATS_ATTR_OUT_OCTETS_PROTECTED , +MACSEC_TXSC_STATS_ATTR_OUT_OCTETS_ENCRYPTED , + __MACSEC_TXSC_STATS_ATTR_END, +NUM_MACSEC_TXSC_STATS_ATTR = __MACSEC_TXSC_STATS_ATTR_END, +MACSEC_TXSC_STATS_ATTR_MAX = __MACSEC_TXSC_STATS_ATTR_END -1 , +}; + +/* u64 per-SecY stats */ +enum macsec_secy_stats_attr { +MACSEC_SECY_STATS_ATTR_UNSPEC , +MACSEC_SECY_STATS_ATTR_OUT_PKTS_UNTAGGED , +MACSEC_SECY_STATS_ATTR_IN_PKTS_UNTAGGED , +MACSEC_SECY_STATS_ATTR_OUT_PKTS_TOO_LONG , +MACSEC_SECY_STATS_ATTR_IN_PKTS_NO_TAG , +MACSEC_SECY_STATS_ATTR_IN_PKTS_BAD_TAG , +MACSEC_SECY_STATS_ATTR_IN_PKTS_UNKNOWN_SCI , +MACSEC_SECY_STATS_ATTR_IN_PKTS_NO_SCI , +MACSEC_SECY_STATS_ATTR_IN_PKTS_OVERRUN , + __MACSEC_SECY_STATS_ATTR_END, +NUM_MACSEC_SECY_STATS_ATTR = __MACSEC_SECY_STATS_ATTR_END, +MACSEC_SECY_STATS_ATTR_MAX = __MACSEC_SECY_STATS_ATTR_END -1 , +}; + +#endif /* _MACSEC_H */
Signature · 1 line
2.8.2
Re: [PATCH iproute2 v3 1/5] add missing if_macsec.h header from kernel
Quoted 2 lines · On Wed, 18 May 2016 17:35:09 +0200 Sabrina Dubroca <[email protected]> wrote:
Signed-off-by Sabrina Dubroca <[email protected]>Acked-by Phil Sutter <[email protected]>
This header already exists in master branch of iproute2, with current version from upstream kernel (with PAD values).
Re: [PATCH iproute2 v3 1/5] add missing if_macsec.h header from kernel
Quoted 8 lines · Stephen Hemminger
Quoted 2 lines · On Wed, 18 May 2016 17:35:09 +0200 Sabrina Dubroca <[email protected]> wrote:
Signed-off-by Sabrina Dubroca <[email protected]>Acked-by Phil Sutter <[email protected]>This header already exists in master branch of iproute2, with current version from upstream kernel (with PAD values).
It wasn't when I posted this ;)
Excellent, I'll drop this patch from v4.
Thanks,
Signature · 1 line
Sabrina
PATCH v3 2/5 utils: make hexstring_a2n provide the number of hex digits parsed
In reply to Sabrina Dubroca--- 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.2
PATCH v3 3/5 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
@@ -171,16 +171,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
@@ -766,12 +766,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;
@@ -801,12 +798,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.2
PATCH v3 4/5 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.2
PATCH v3 5/5 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
--- ip/Makefile | 2 +- ip/ip.c | 3 +- ip/ip_common.h | 1 + ip/ipmacsec.c | 1236 +++++++++++++++++++++++++++++++++++++++++++++++++ man/man8/Makefile | 2 +- man/man8/ip-link.8.in | 85 ++++ man/man8/ip-macsec.8 | 98 ++++ 7 files changed, 1424 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 +1236 -0
1,236 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.2
Re: [PATCH iproute2 v3 5/5] ip: add MACsec support
ip/ipmacsec.c line 816
Quoted 3 lines · On Wed, 18 May 2016 17:35:13 +0200 Sabrina Dubroca <[email protected]> wrote:
ip/ipmacsec.c new file +3
-0+ +static void print_rx_sc (const char *prefix,__u64 sci,__u8 active,struct rtattr *rxsc_stats,struct rtattr *sa) +{
Overall, this looks fine, but could you break some of the really long lines. In general, I like iproute2 to follow kernel style, and in general stick to the 80 column recommendation where it makes sense. Spliting strings or stuff in loops may not make sense. There are several places in this code longer than 100 chars.
Re: [PATCH iproute2 v3 5/5] ip: add MACsec support
Hello Stephen,
Quoted 12 lines · Stephen Hemminger
ip/ipmacsec.c line 816
Quoted 3 lines · On Wed, 18 May 2016 17:35:13 +0200 Sabrina Dubroca <[email protected]> wrote:
ip/ipmacsec.c new file +3
-0+ +static void print_rx_sc (const char *prefix,__u64 sci,__u8 active,struct rtattr *rxsc_stats,struct rtattr *sa) +{Overall, this looks fine, but could you break some of the really long lines. In general, I like iproute2 to follow kernel style, and in general stick to the 80 column recommendation where it makes sense. Spliting strings or stuff in loops may not make sense. There are several places in this code longer than 100 chars.
Ugh, yeah, I forgot to clean this up, sorry.
I'll do that and resend.
Thanks,
Signature · 1 line
Sabrina