From 5cf576d928c515ce8dea2500154a291477ce38ba Mon Sep 17 00:00:00 2001 From: "osdl.net!shemminger" Date: Thu, 10 Mar 2005 19:04:00 +0000 Subject: [PATCH] Add Esp-in-udp encapsulation (Logical change 1.152) --- ip/ipxfrm.c | 39 ++++++++++++++++++++++++++++++++++----- ip/xfrm.h | 1 + ip/xfrm_state.c | 24 ++++++++++++++++++++++-- 3 files changed, 57 insertions(+), 7 deletions(-) diff --git a/ip/ipxfrm.c b/ip/ipxfrm.c index 836e11ac..fc0f0d9a 100644 --- a/ip/ipxfrm.c +++ b/ip/ipxfrm.c @@ -571,19 +571,19 @@ void xfrm_xfrma_print(struct rtattr *tb[], __u16 family, if (tb[XFRMA_ALG_AUTH]) { struct rtattr *rta = tb[XFRMA_ALG_AUTH]; xfrm_algo_print((struct xfrm_algo *) RTA_DATA(rta), - XFRMA_ALG_AUTH, RTA_PAYLOAD(rta), fp, prefix); + XFRMA_ALG_AUTH, RTA_PAYLOAD(rta), fp, prefix); } if (tb[XFRMA_ALG_CRYPT]) { struct rtattr *rta = tb[XFRMA_ALG_CRYPT]; xfrm_algo_print((struct xfrm_algo *) RTA_DATA(rta), - XFRMA_ALG_CRYPT, RTA_PAYLOAD(rta), fp, prefix); + XFRMA_ALG_CRYPT, RTA_PAYLOAD(rta), fp, prefix); } if (tb[XFRMA_ALG_COMP]) { struct rtattr *rta = tb[XFRMA_ALG_COMP]; xfrm_algo_print((struct xfrm_algo *) RTA_DATA(rta), - XFRMA_ALG_COMP, RTA_PAYLOAD(rta), fp, prefix); + XFRMA_ALG_COMP, RTA_PAYLOAD(rta), fp, prefix); } if (tb[XFRMA_ENCAP]) { @@ -601,7 +601,18 @@ void xfrm_xfrma_print(struct rtattr *tb[], __u16 family, } e = (struct xfrm_encap_tmpl *) RTA_DATA(tb[XFRMA_ENCAP]); - fprintf(fp, "type %u ", e->encap_type); + fprintf(fp, "type "); + switch (e->encap_type) { + case 1: + fprintf(fp, "espinudp-nonike "); + break; + case 2: + fprintf(fp, "espinudp "); + break; + default: + fprintf(fp, "%u ", e->encap_type); + break; + } fprintf(fp, "sport %u ", ntohs(e->encap_sport)); fprintf(fp, "dport %u ", ntohs(e->encap_dport)); @@ -615,7 +626,7 @@ void xfrm_xfrma_print(struct rtattr *tb[], __u16 family, if (tb[XFRMA_TMPL]) { struct rtattr *rta = tb[XFRMA_TMPL]; xfrm_tmpl_print((struct xfrm_user_tmpl *) RTA_DATA(rta), - RTA_PAYLOAD(rta), family, fp, prefix); + RTA_PAYLOAD(rta), family, fp, prefix); } } @@ -724,6 +735,24 @@ int xfrm_mode_parse(__u8 *mode, int *argcp, char ***argvp) return 0; } +int xfrm_encap_type_parse(__u16 *type, int *argcp, char ***argvp) +{ + int argc = *argcp; + char **argv = *argvp; + + if (strcmp(*argv, "espinudp-nonike") == 0) + *type = 1; + else if (strcmp(*argv, "espinudp") == 0) + *type = 2; + else + invarg("\"ENCAP-TYPE\" is invalid", *argv); + + *argcp = argc; + *argvp = argv; + + return 0; +} + /* NOTE: reqid is used by host-byte order */ int xfrm_reqid_parse(__u32 *reqid, int *argcp, char ***argvp) { diff --git a/ip/xfrm.h b/ip/xfrm.h index 9f09885e..fa551b18 100644 --- a/ip/xfrm.h +++ b/ip/xfrm.h @@ -110,6 +110,7 @@ void xfrm_xfrma_print(struct rtattr *tb[], __u16 family, int xfrm_id_parse(xfrm_address_t *saddr, struct xfrm_id *id, __u16 *family, int loose, int *argcp, char ***argvp); int xfrm_mode_parse(__u8 *mode, int *argcp, char ***argvp); +int xfrm_encap_type_parse(__u16 *type, int *argcp, char ***argvp); int xfrm_reqid_parse(__u32 *reqid, int *argcp, char ***argvp); int xfrm_selector_parse(struct xfrm_selector *sel, int *argcp, char ***argvp); int xfrm_lifetime_cfg_parse(struct xfrm_lifetime_cfg *lft, diff --git a/ip/xfrm_state.c b/ip/xfrm_state.c index b6481975..b5b62146 100644 --- a/ip/xfrm_state.c +++ b/ip/xfrm_state.c @@ -57,8 +57,7 @@ static void usage(void) { fprintf(stderr, "Usage: ip xfrm state { add | update } ID [ ALGO-LIST ] [ mode MODE ]\n"); fprintf(stderr, " [ reqid REQID ] [ replay-window SIZE ] [ flag FLAG-LIST ]\n"); - fprintf(stderr, " [ sel SELECTOR ] [ LIMIT-LIST ]\n"); - + fprintf(stderr, " [ encap ENCAP ] [ sel SELECTOR ] [ LIMIT-LIST ]\n"); fprintf(stderr, "Usage: ip xfrm state { delete | get } ID\n"); fprintf(stderr, "Usage: ip xfrm state { flush | list } [ ID ] [ mode MODE ] [ reqid REQID ]\n"); fprintf(stderr, " [ flag FLAG_LIST ]\n"); @@ -78,6 +77,9 @@ static void usage(void) fprintf(stderr, "FLAG-LIST := [ FLAG-LIST ] FLAG\n"); fprintf(stderr, "FLAG := [ noecn | decap-dscp ]\n"); + + fprintf(stderr, "ENCAP := ENCAP-TYPE SPORT DPORT OADDR\n"); + fprintf(stderr, "ENCAP-TYPE := espinudp | espinudp-nonike\n"); fprintf(stderr, "ALGO-LIST := [ ALGO-LIST ] | [ ALGO ]\n"); fprintf(stderr, "ALGO := ALGO_TYPE ALGO_NAME ALGO_KEY\n"); @@ -243,6 +245,24 @@ static int xfrm_state_modify(int cmd, unsigned flags, int argc, char **argv) } else if (strcmp(*argv, "limit") == 0) { NEXT_ARG(); xfrm_lifetime_cfg_parse(&req.xsinfo.lft, &argc, &argv); + } else if (strcmp(*argv, "encap") == 0) { + struct xfrm_encap_tmpl encap; + inet_prefix oa; + NEXT_ARG(); + xfrm_encap_type_parse(&encap.encap_type, &argc, &argv); + NEXT_ARG(); + if (get_u16(&encap.encap_sport, *argv, 0)) + invarg("\"encap\" sport value is invalid", *argv); + encap.encap_sport = htons(encap.encap_sport); + NEXT_ARG(); + if (get_u16(&encap.encap_dport, *argv, 0)) + invarg("\"encap\" dport value 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)); + addattr_l(&req.n, sizeof(req.buf), XFRMA_ENCAP, + (void *)&encap, sizeof(encap)); } else { /* try to assume ALGO */ int type = xfrm_algotype_getbyname(*argv);