|
24 | 24 |
|
25 | 25 | #include "test_progs.h"
|
26 | 26 | #include "network_helpers.h"
|
| 27 | +#include "netlink_helpers.h" |
27 | 28 | #include "test_tc_neigh_fib.skel.h"
|
28 | 29 | #include "test_tc_neigh.skel.h"
|
29 | 30 | #include "test_tc_peer.skel.h"
|
@@ -112,6 +113,7 @@ static void netns_setup_namespaces_nofail(const char *verb)
|
112 | 113 |
|
113 | 114 | enum dev_mode {
|
114 | 115 | MODE_VETH,
|
| 116 | + MODE_NETKIT, |
115 | 117 | };
|
116 | 118 |
|
117 | 119 | struct netns_setup_result {
|
@@ -142,17 +144,65 @@ static int get_ifaddr(const char *name, char *ifaddr)
|
142 | 144 | return 0;
|
143 | 145 | }
|
144 | 146 |
|
| 147 | +static int create_netkit(int mode, char *prim, char *peer) |
| 148 | +{ |
| 149 | + struct rtattr *linkinfo, *data, *peer_info; |
| 150 | + struct rtnl_handle rth = { .fd = -1 }; |
| 151 | + const char *type = "netkit"; |
| 152 | + struct { |
| 153 | + struct nlmsghdr n; |
| 154 | + struct ifinfomsg i; |
| 155 | + char buf[1024]; |
| 156 | + } req = {}; |
| 157 | + int err; |
| 158 | + |
| 159 | + err = rtnl_open(&rth, 0); |
| 160 | + if (!ASSERT_OK(err, "open_rtnetlink")) |
| 161 | + return err; |
| 162 | + |
| 163 | + memset(&req, 0, sizeof(req)); |
| 164 | + req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); |
| 165 | + req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL; |
| 166 | + req.n.nlmsg_type = RTM_NEWLINK; |
| 167 | + req.i.ifi_family = AF_UNSPEC; |
| 168 | + |
| 169 | + addattr_l(&req.n, sizeof(req), IFLA_IFNAME, prim, strlen(prim)); |
| 170 | + linkinfo = addattr_nest(&req.n, sizeof(req), IFLA_LINKINFO); |
| 171 | + addattr_l(&req.n, sizeof(req), IFLA_INFO_KIND, type, strlen(type)); |
| 172 | + data = addattr_nest(&req.n, sizeof(req), IFLA_INFO_DATA); |
| 173 | + addattr32(&req.n, sizeof(req), IFLA_NETKIT_MODE, mode); |
| 174 | + peer_info = addattr_nest(&req.n, sizeof(req), IFLA_NETKIT_PEER_INFO); |
| 175 | + req.n.nlmsg_len += sizeof(struct ifinfomsg); |
| 176 | + addattr_l(&req.n, sizeof(req), IFLA_IFNAME, peer, strlen(peer)); |
| 177 | + addattr_nest_end(&req.n, peer_info); |
| 178 | + addattr_nest_end(&req.n, data); |
| 179 | + addattr_nest_end(&req.n, linkinfo); |
| 180 | + |
| 181 | + err = rtnl_talk(&rth, &req.n, NULL); |
| 182 | + ASSERT_OK(err, "talk_rtnetlink"); |
| 183 | + rtnl_close(&rth); |
| 184 | + return err; |
| 185 | +} |
| 186 | + |
145 | 187 | static int netns_setup_links_and_routes(struct netns_setup_result *result)
|
146 | 188 | {
|
147 | 189 | struct nstoken *nstoken = NULL;
|
148 | 190 | char src_fwd_addr[IFADDR_STR_LEN+1] = {};
|
| 191 | + int err; |
149 | 192 |
|
150 | 193 | if (result->dev_mode == MODE_VETH) {
|
151 | 194 | SYS(fail, "ip link add src type veth peer name src_fwd");
|
152 | 195 | SYS(fail, "ip link add dst type veth peer name dst_fwd");
|
153 | 196 |
|
154 | 197 | SYS(fail, "ip link set dst_fwd address " MAC_DST_FWD);
|
155 | 198 | SYS(fail, "ip link set dst address " MAC_DST);
|
| 199 | + } else if (result->dev_mode == MODE_NETKIT) { |
| 200 | + err = create_netkit(NETKIT_L3, "src", "src_fwd"); |
| 201 | + if (!ASSERT_OK(err, "create_ifindex_src")) |
| 202 | + goto fail; |
| 203 | + err = create_netkit(NETKIT_L3, "dst", "dst_fwd"); |
| 204 | + if (!ASSERT_OK(err, "create_ifindex_dst")) |
| 205 | + goto fail; |
156 | 206 | }
|
157 | 207 |
|
158 | 208 | if (get_ifaddr("src_fwd", src_fwd_addr))
|
@@ -1134,7 +1184,9 @@ static void *test_tc_redirect_run_tests(void *arg)
|
1134 | 1184 | netns_setup_namespaces_nofail("delete");
|
1135 | 1185 |
|
1136 | 1186 | RUN_TEST(tc_redirect_peer, MODE_VETH);
|
| 1187 | + RUN_TEST(tc_redirect_peer, MODE_NETKIT); |
1137 | 1188 | RUN_TEST(tc_redirect_peer_l3, MODE_VETH);
|
| 1189 | + RUN_TEST(tc_redirect_peer_l3, MODE_NETKIT); |
1138 | 1190 | RUN_TEST(tc_redirect_neigh, MODE_VETH);
|
1139 | 1191 | RUN_TEST(tc_redirect_neigh_fib, MODE_VETH);
|
1140 | 1192 | RUN_TEST(tc_redirect_dtime, MODE_VETH);
|
|
0 commit comments