From patchwork Wed Nov 24 08:18:58 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [2/2] iproute2: support xfrm upper protocol gre key Date: Tue, 23 Nov 2010 22:18:58 -0000 From: =?utf-8?b?VGltbyBUZXLDpHMgPHRpbW8udGVyYXNAaWtpLmZpPg==?= X-Patchwork-Id: 72812 Message-Id: <1290586738-27056-2-git-send-email-timo.teras@iki.fi> To: shemminger@linux-foundation.org, netdev@vger.kernel.org Cc: =?UTF-8?q?Timo=20Ter=C3=A4s?= Similar to tunnel side: accept dotted-quad and number formats. Use regular number for printing the key. Signed-off-by: Timo Teräs --- I decided to keep using get_addr32() and get_unsigned() since uclibc inet_aton() does not accept all formats. ip/ipxfrm.c | 39 +++++++++++++++++++++++++++++++++++++++ ip/xfrm_policy.c | 3 ++- man/man8/ip.8 | 25 ++++++++++++++++--------- 3 files changed, 57 insertions(+), 10 deletions(-) diff --git a/ip/ipxfrm.c b/ip/ipxfrm.c index 99a6756..9753822 100644 --- a/ip/ipxfrm.c +++ b/ip/ipxfrm.c @@ -483,6 +483,12 @@ void xfrm_selector_print(struct xfrm_selector *sel, __u16 family, if (sel->dport_mask) fprintf(fp, "code %u ", ntohs(sel->dport)); break; + case IPPROTO_GRE: + if (sel->sport_mask || sel->dport_mask) + fprintf(fp, "key %u ", + (((__u32)ntohs(sel->sport)) << 16) + + ntohs(sel->dport)); + break; case IPPROTO_MH: if (sel->sport_mask) fprintf(fp, "type %u ", ntohs(sel->sport)); @@ -1086,6 +1092,7 @@ static int xfrm_selector_upspec_parse(struct xfrm_selector *sel, char *dportp = NULL; char *typep = NULL; char *codep = NULL; + char *grekey = NULL; while (1) { if (strcmp(*argv, "proto") == 0) { @@ -1162,6 +1169,29 @@ static int xfrm_selector_upspec_parse(struct xfrm_selector *sel, filter.upspec_dport_mask = XFRM_FILTER_MASK_FULL; + } else if (strcmp(*argv, "key") == 0) { + unsigned uval; + + grekey = *argv; + + NEXT_ARG(); + + if (strchr(*argv, '.')) + uval = htonl(get_addr32(*argv)); + else { + if (get_unsigned(&uval, *argv, 0)<0) { + fprintf(stderr, "invalid value of \"key\"\n"); + exit(-1); + } + } + + sel->sport = htons(uval >> 16); + sel->dport = htons(uval & 0xffff); + sel->sport_mask = ~((__u16)0); + sel->dport_mask = ~((__u16)0); + + filter.upspec_dport_mask = XFRM_FILTER_MASK_FULL; + } else { PREV_ARG(); /* back track */ break; @@ -1196,6 +1226,15 @@ static int xfrm_selector_upspec_parse(struct xfrm_selector *sel, exit(1); } } + if (grekey) { + switch (sel->proto) { + case IPPROTO_GRE: + break; + default: + fprintf(stderr, "\"key\" is invalid with proto=%s\n", strxf_proto(sel->proto)); + exit(1); + } + } *argcp = argc; *argvp = argv; diff --git a/ip/xfrm_policy.c b/ip/xfrm_policy.c index 121afa1..dcb3da4 100644 --- a/ip/xfrm_policy.c +++ b/ip/xfrm_policy.c @@ -66,7 +66,8 @@ static void usage(void) fprintf(stderr, "SELECTOR := src ADDR[/PLEN] dst ADDR[/PLEN] [ UPSPEC ] [ dev DEV ]\n"); fprintf(stderr, "UPSPEC := proto PROTO [ [ sport PORT ] [ dport PORT ] |\n"); - fprintf(stderr, " [ type NUMBER ] [ code NUMBER ] ]\n"); + fprintf(stderr, " [ type NUMBER ] [ code NUMBER ] |\n"); + fprintf(stderr, " [ key { DOTTED_QUAD | NUMBER } ] ]\n"); //fprintf(stderr, "DEV - device name(default=none)\n"); diff --git a/man/man8/ip.8 b/man/man8/ip.8 index 1a73efa..c1e03f3 100644 --- a/man/man8/ip.8 +++ b/man/man8/ip.8 @@ -547,7 +547,10 @@ throw " | " unreachable " | " prohibit " | " blackhole " | " nat " ]" .RB " [ " type .IR NUMBER " ] " .RB " [ " code -.IR NUMBER " ]] " +.IR NUMBER " ] | " +.br +.RB " [ " key +.IR KEY " ]] " .ti -8 .IR LIMIT-LIST " := [ " LIMIT-LIST " ] |" @@ -642,7 +645,10 @@ throw " | " unreachable " | " prohibit " | " blackhole " | " nat " ]" .RB " [ " type .IR NUMBER " ] " .RB " [ " code -.IR NUMBER " ] ] " +.IR NUMBER " ] | " +.br +.RB " [ " key +.IR KEY " ] ] " .ti -8 .IR ACTION " := " @@ -2487,9 +2493,11 @@ is defined by source port .BR sport ", " destination port .BR dport ", " type -as number and +as number, .B code -also number. +also number and +.BR key +as dotted-quad or number. .TP .BI dev " DEV " @@ -2556,11 +2564,10 @@ and the other choice is .TP .IR UPSPEC is specified by -.BR sport ", " -.BR dport ", " type -and -.B code -(NUMBER). +.BR sport " and " dport " (for UDP/TCP), " +.BR type " and " code " (for ICMP; as number) or " +.BR key " (for GRE; as dotted-quad or number)." +. .SS ip xfrm monitor - is used for listing all objects or defined group of them. The