]> rtime.felk.cvut.cz Git - lisovros/iproute2_canprio.git/commitdiff
xfrm: add support for SA by mark
authorJamal Hadi Salim <hadi@cyberus.ca>
Tue, 23 Feb 2010 03:15:12 +0000 (03:15 +0000)
committerStephen Hemminger <stephen.hemminger@vyatta.com>
Thu, 4 Mar 2010 00:37:29 +0000 (16:37 -0800)
Add support for SA manipulation by mark

Signed-off-by: Jamal Hadi Salim <hadi@cyberus.ca>
ip/xfrm_state.c

index 32238ab7a5dec7130403e4779dbf558ddd78551e..38d40391e3839dd51b1a9250170253d34ea2f67a 100644 (file)
@@ -67,7 +67,7 @@ static void usage(void)
        fprintf(stderr, "Usage: ip xfrm state flush [ proto XFRM_PROTO ]\n");
        fprintf(stderr, "Usage: ip xfrm state count \n");
 
-       fprintf(stderr, "ID := [ src ADDR ] [ dst ADDR ] [ proto XFRM_PROTO ] [ spi SPI ]\n");
+       fprintf(stderr, "ID := [ src ADDR ] [ dst ADDR ] [ proto XFRM_PROTO ] [ spi SPI ] [mark MARK [mask MASK]]\n");
        //fprintf(stderr, "XFRM_PROTO := [ esp | ah | comp ]\n");
        fprintf(stderr, "XFRM_PROTO := [ ");
        fprintf(stderr, "%s | ", strxf_xfrmproto(IPPROTO_ESP));
@@ -246,6 +246,7 @@ static int xfrm_state_modify(int cmd, unsigned flags, int argc, char **argv)
        char *aalgop = NULL;
        char *calgop = NULL;
        char *coap = NULL;
+       struct xfrm_mark mark = {0, 0};
 
        memset(&req, 0, sizeof(req));
        memset(&replay, 0, sizeof(replay));
@@ -264,6 +265,8 @@ static int xfrm_state_modify(int cmd, unsigned flags, int argc, char **argv)
                if (strcmp(*argv, "mode") == 0) {
                        NEXT_ARG();
                        xfrm_mode_parse(&req.xsinfo.mode, &argc, &argv);
+               } else if (strcmp(*argv, "mark") == 0) {
+                       xfrm_parse_mark(&mark, &argc, &argv);
                } else if (strcmp(*argv, "reqid") == 0) {
                        NEXT_ARG();
                        xfrm_reqid_parse(&req.xsinfo.reqid, &argc, &argv);
@@ -440,6 +443,15 @@ parse_algo:
                exit(1);
        }
 
+       if (mark.m & mark.v) {
+               int r = addattr_l(&req.n, sizeof(req.buf), XFRMA_MARK,
+                                 (void *)&mark, sizeof(mark));
+               if (r < 0) {
+                       fprintf(stderr, "XFRMA_MARK failed\n");
+                       exit(1);
+               }
+       }
+
        switch (req.xsinfo.mode) {
        case XFRM_MODE_TRANSPORT:
        case XFRM_MODE_TUNNEL:
@@ -519,6 +531,7 @@ static int xfrm_state_allocspi(int argc, char **argv)
        char *idp = NULL;
        char *minp = NULL;
        char *maxp = NULL;
+       struct xfrm_mark mark = {0, 0};
        char res_buf[NLMSG_BUF_SIZE];
        struct nlmsghdr *res_n = (struct nlmsghdr *)res_buf;
 
@@ -542,6 +555,8 @@ static int xfrm_state_allocspi(int argc, char **argv)
                if (strcmp(*argv, "mode") == 0) {
                        NEXT_ARG();
                        xfrm_mode_parse(&req.xspi.info.mode, &argc, &argv);
+               } else if (strcmp(*argv, "mark") == 0) {
+                       xfrm_parse_mark(&mark, &argc, &argv);
                } else if (strcmp(*argv, "reqid") == 0) {
                        NEXT_ARG();
                        xfrm_reqid_parse(&req.xspi.info.reqid, &argc, &argv);
@@ -618,6 +633,15 @@ static int xfrm_state_allocspi(int argc, char **argv)
                        req.xspi.max = 0xffff;
        }
 
+       if (mark.m & mark.v) {
+               int r = addattr_l(&req.n, sizeof(req.buf), XFRMA_MARK,
+                                 (void *)&mark, sizeof(mark));
+               if (r < 0) {
+                       fprintf(stderr, "XFRMA_MARK failed\n");
+                       exit(1);
+               }
+       }
+
        if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
                exit(1);
 
@@ -763,6 +787,7 @@ static int xfrm_state_get_or_delete(int argc, char **argv, int delete)
        } req;
        struct xfrm_id id;
        char *idp = NULL;
+       struct xfrm_mark mark = {0, 0};
 
        memset(&req, 0, sizeof(req));
 
@@ -774,26 +799,39 @@ static int xfrm_state_get_or_delete(int argc, char **argv, int delete)
        while (argc > 0) {
                xfrm_address_t saddr;
 
-               if (idp)
-                       invarg("unknown", *argv);
-               idp = *argv;
+               if (strcmp(*argv, "mark") == 0) {
+                       xfrm_parse_mark(&mark, &argc, &argv);
+               } else {
+                       if (idp)
+                               invarg("unknown", *argv);
+                       idp = *argv;
 
-               /* ID */
-               memset(&id, 0, sizeof(id));
-               memset(&saddr, 0, sizeof(saddr));
-               xfrm_id_parse(&saddr, &id, &req.xsid.family, 0,
-                             &argc, &argv);
+                       /* ID */
+                       memset(&id, 0, sizeof(id));
+                       memset(&saddr, 0, sizeof(saddr));
+                       xfrm_id_parse(&saddr, &id, &req.xsid.family, 0,
+                                     &argc, &argv);
 
-               memcpy(&req.xsid.daddr, &id.daddr, sizeof(req.xsid.daddr));
-               req.xsid.spi = id.spi;
-               req.xsid.proto = id.proto;
+                       memcpy(&req.xsid.daddr, &id.daddr, sizeof(req.xsid.daddr));
+                       req.xsid.spi = id.spi;
+                       req.xsid.proto = id.proto;
 
-               addattr_l(&req.n, sizeof(req.buf), XFRMA_SRCADDR,
-                         (void *)&saddr, sizeof(saddr));
+                       addattr_l(&req.n, sizeof(req.buf), XFRMA_SRCADDR,
+                                 (void *)&saddr, sizeof(saddr));
+               }
 
                argc--; argv++;
        }
 
+       if (mark.m & mark.v) {
+               int r = addattr_l(&req.n, sizeof(req.buf), XFRMA_MARK,
+                                 (void *)&mark, sizeof(mark));
+               if (r < 0) {
+                       fprintf(stderr, "XFRMA_MARK failed\n");
+                       exit(1);
+               }
+       }
+
        if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
                exit(1);