]>
git.proxmox.com Git - mirror_iproute2.git/blob - ip/ipfou.c
2 * ipfou.c FOU (foo over UDP) support
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
9 * Authors: Tom Herbert <therbert@google.com>
17 #include <linux/fou.h>
18 #include <linux/genetlink.h>
20 #include <arpa/inet.h>
24 #include "ip_common.h"
26 static void usage(void)
28 fprintf(stderr
, "Usage: ip fou add port PORT { ipproto PROTO | gue }\n");
29 fprintf(stderr
, " ip fou del port PORT\n");
30 fprintf(stderr
, "\n");
31 fprintf(stderr
, "Where: PROTO { ipproto-name | 1..255 }\n");
32 fprintf(stderr
, " PORT { 1..65535 }\n");
38 static struct rtnl_handle genl_rth
= { .fd
= -1 };
39 static int genl_family
= -1;
41 #define FOU_REQUEST(_req, _bufsiz, _cmd, _flags) \
42 GENL_REQUEST(_req, _bufsiz, genl_family, 0, \
43 FOU_GENL_VERSION, _cmd, _flags)
45 static int fou_parse_opt(int argc
, char **argv
, struct nlmsghdr
*n
,
55 if (!matches(*argv
, "port")) {
58 if (get_u16(&port
, *argv
, 0) || port
== 0)
59 invarg("invalid port", *argv
);
62 } else if (!matches(*argv
, "ipproto")) {
63 struct protoent
*servptr
;
67 servptr
= getprotobyname(*argv
);
69 ipproto
= servptr
->p_proto
;
70 else if (get_u8(&ipproto
, *argv
, 0) || ipproto
== 0)
71 invarg("invalid ipproto", *argv
);
73 } else if (!matches(*argv
, "gue")) {
76 fprintf(stderr
, "fou: unknown command \"%s\"?\n", *argv
);
84 fprintf(stderr
, "fou: missing port\n");
88 if (!ipproto_set
&& !gue_set
&& adding
) {
89 fprintf(stderr
, "fou: must set ipproto or gue\n");
93 if (ipproto_set
&& gue_set
) {
94 fprintf(stderr
, "fou: cannot set ipproto and gue\n");
98 type
= gue_set
? FOU_ENCAP_GUE
: FOU_ENCAP_DIRECT
;
100 addattr16(n
, 1024, FOU_ATTR_PORT
, port
);
101 addattr8(n
, 1024, FOU_ATTR_TYPE
, type
);
104 addattr8(n
, 1024, FOU_ATTR_IPPROTO
, ipproto
);
109 static int do_add(int argc
, char **argv
)
111 FOU_REQUEST(req
, 1024, FOU_CMD_ADD
, NLM_F_REQUEST
);
113 fou_parse_opt(argc
, argv
, &req
.n
, true);
115 if (rtnl_talk(&genl_rth
, &req
.n
, NULL
, 0) < 0)
121 static int do_del(int argc
, char **argv
)
123 FOU_REQUEST(req
, 1024, FOU_CMD_DEL
, NLM_F_REQUEST
);
125 fou_parse_opt(argc
, argv
, &req
.n
, false);
127 if (rtnl_talk(&genl_rth
, &req
.n
, NULL
, 0) < 0)
133 int do_ipfou(int argc
, char **argv
)
135 if (genl_family
< 0) {
136 if (rtnl_open_byproto(&genl_rth
, 0, NETLINK_GENERIC
) < 0) {
137 fprintf(stderr
, "Cannot open generic netlink socket\n");
141 genl_family
= genl_resolve_family(&genl_rth
, FOU_GENL_NAME
);
149 if (matches(*argv
, "add") == 0)
150 return do_add(argc
-1, argv
+1);
151 if (matches(*argv
, "delete") == 0)
152 return do_del(argc
-1, argv
+1);
153 if (matches(*argv
, "help") == 0)
156 fprintf(stderr
, "Command \"%s\" is unknown, try \"ip fou help\".\n", *argv
);