1 /* iplink_vrf.c VRF device support
3 * This program is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU General Public License
5 * as published by the Free Software Foundation; either version
6 * 2 of the License, or (at your option) any later version.
8 * Authors: Shrijeet Mukherjee <shm@cumulusnetworks.com>
14 #include <sys/socket.h>
15 #include <linux/if_link.h>
19 #include "ip_common.h"
21 static void vrf_explain(FILE *f
)
23 fprintf(f
, "Usage: ... vrf table TABLEID\n");
26 static void explain(void)
31 static int vrf_parse_opt(struct link_util
*lu
, int argc
, char **argv
,
35 if (matches(*argv
, "table") == 0) {
40 if (rtnl_rttable_a2n(&table
, *argv
))
41 invarg("invalid table ID\n", *argv
);
42 addattr32(n
, 1024, IFLA_VRF_TABLE
, table
);
43 } else if (matches(*argv
, "help") == 0) {
47 fprintf(stderr
, "vrf: unknown option \"%s\"?\n",
58 static void vrf_print_opt(struct link_util
*lu
, FILE *f
, struct rtattr
*tb
[])
63 if (tb
[IFLA_VRF_TABLE
])
64 fprintf(f
, "table %u ", rta_getattr_u32(tb
[IFLA_VRF_TABLE
]));
67 static void vrf_slave_print_opt(struct link_util
*lu
, FILE *f
,
73 if (tb
[IFLA_VRF_PORT_TABLE
]) {
74 fprintf(f
, "table %u ",
75 rta_getattr_u32(tb
[IFLA_VRF_PORT_TABLE
]));
79 static void vrf_print_help(struct link_util
*lu
, int argc
, char **argv
,
85 struct link_util vrf_link_util
= {
87 .maxattr
= IFLA_VRF_MAX
,
88 .parse_opt
= vrf_parse_opt
,
89 .print_opt
= vrf_print_opt
,
90 .print_help
= vrf_print_help
,
93 struct link_util vrf_slave_link_util
= {
95 .maxattr
= IFLA_VRF_PORT_MAX
,
96 .print_opt
= vrf_slave_print_opt
,
99 /* returns table id if name is a VRF device */
100 __u32
ipvrf_get_table(const char *name
)
108 .nlmsg_len
= NLMSG_LENGTH(sizeof(struct ifinfomsg
)),
109 .nlmsg_flags
= NLM_F_REQUEST
,
110 .nlmsg_type
= RTM_GETLINK
,
113 .ifi_family
= preferred_family
,
120 struct rtattr
*tb
[IFLA_MAX
+1];
121 struct rtattr
*li
[IFLA_INFO_MAX
+1];
122 struct rtattr
*vrf_attr
[IFLA_VRF_MAX
+ 1];
123 struct ifinfomsg
*ifi
;
127 addattr_l(&req
.n
, sizeof(req
), IFLA_IFNAME
, name
, strlen(name
) + 1);
129 if (rtnl_talk(&rth
, &req
.n
, &answer
.n
, sizeof(answer
)) < 0)
132 ifi
= NLMSG_DATA(&answer
.n
);
133 len
= answer
.n
.nlmsg_len
- NLMSG_LENGTH(sizeof(*ifi
));
135 fprintf(stderr
, "BUG: Invalid response to link query.\n");
139 parse_rtattr(tb
, IFLA_MAX
, IFLA_RTA(ifi
), len
);
141 if (!tb
[IFLA_LINKINFO
])
144 parse_rtattr_nested(li
, IFLA_INFO_MAX
, tb
[IFLA_LINKINFO
]);
146 if (!li
[IFLA_INFO_KIND
] || !li
[IFLA_INFO_DATA
])
149 if (strcmp(RTA_DATA(li
[IFLA_INFO_KIND
]), "vrf"))
152 parse_rtattr_nested(vrf_attr
, IFLA_VRF_MAX
, li
[IFLA_INFO_DATA
]);
153 if (vrf_attr
[IFLA_VRF_TABLE
])
154 tb_id
= rta_getattr_u32(vrf_attr
[IFLA_VRF_TABLE
]);
157 fprintf(stderr
, "BUG: VRF %s is missing table id\n", name
);
162 bool name_is_vrf(const char *name
)
170 .nlmsg_len
= NLMSG_LENGTH(sizeof(struct ifinfomsg
)),
171 .nlmsg_flags
= NLM_F_REQUEST
,
172 .nlmsg_type
= RTM_GETLINK
,
175 .ifi_family
= preferred_family
,
182 struct rtattr
*tb
[IFLA_MAX
+1];
183 struct rtattr
*li
[IFLA_INFO_MAX
+1];
184 struct ifinfomsg
*ifi
;
187 addattr_l(&req
.n
, sizeof(req
), IFLA_IFNAME
, name
, strlen(name
) + 1);
189 if (rtnl_talk(&rth
, &req
.n
, &answer
.n
, sizeof(answer
)) < 0)
192 ifi
= NLMSG_DATA(&answer
.n
);
193 len
= answer
.n
.nlmsg_len
- NLMSG_LENGTH(sizeof(*ifi
));
195 fprintf(stderr
, "BUG: Invalid response to link query.\n");
199 parse_rtattr(tb
, IFLA_MAX
, IFLA_RTA(ifi
), len
);
201 if (!tb
[IFLA_LINKINFO
])
204 parse_rtattr_nested(li
, IFLA_INFO_MAX
, tb
[IFLA_LINKINFO
]);
206 if (!li
[IFLA_INFO_KIND
])
209 return strcmp(RTA_DATA(li
[IFLA_INFO_KIND
]), "vrf") == 0;