diff options
Diffstat (limited to 'src/fnet/veth.c')
-rw-r--r-- | src/fnet/veth.c | 61 |
1 files changed, 60 insertions, 1 deletions
diff --git a/src/fnet/veth.c b/src/fnet/veth.c index c971943a7..fb4f3dc31 100644 --- a/src/fnet/veth.c +++ b/src/fnet/veth.c | |||
@@ -165,8 +165,66 @@ int net_create_macvlan(const char *dev, const char *parent, unsigned pid) { | |||
165 | addattr_l (&req.n, sizeof(req), IFLA_INFO_KIND, &macvlan_type, 4); | 165 | addattr_l (&req.n, sizeof(req), IFLA_INFO_KIND, &macvlan_type, 4); |
166 | 166 | ||
167 | data->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)data; | 167 | data->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)data; |
168 | // req.n.nlmsg_len += sizeof(struct ifinfomsg); | 168 | linkinfo->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)linkinfo; |
169 | |||
170 | // send message | ||
171 | if (rtnl_talk(&rth, &req.n, 0, 0, NULL) < 0) | ||
172 | exit(2); | ||
173 | |||
174 | rtnl_close(&rth); | ||
169 | 175 | ||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | int net_create_ipvlan(const char *dev, const char *parent, unsigned pid) { | ||
180 | int len; | ||
181 | struct iplink_req req; | ||
182 | assert(dev); | ||
183 | assert(parent); | ||
184 | |||
185 | if (rtnl_open(&rth, 0) < 0) { | ||
186 | fprintf(stderr, "cannot open netlink\n"); | ||
187 | exit(1); | ||
188 | } | ||
189 | |||
190 | memset(&req, 0, sizeof(req)); | ||
191 | |||
192 | req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); | ||
193 | req.n.nlmsg_flags = NLM_F_REQUEST|NLM_F_CREATE|NLM_F_EXCL; | ||
194 | req.n.nlmsg_type = RTM_NEWLINK; | ||
195 | req.i.ifi_family = 0; | ||
196 | |||
197 | // find parent ifindex | ||
198 | int parent_ifindex = if_nametoindex(parent); | ||
199 | if (parent_ifindex <= 0) { | ||
200 | fprintf(stderr, "Error: cannot find network device %s\n", parent); | ||
201 | exit(1); | ||
202 | } | ||
203 | |||
204 | // add parent | ||
205 | addattr_l(&req.n, sizeof(req), IFLA_LINK, &parent_ifindex, 4); | ||
206 | |||
207 | // add new interface name | ||
208 | len = strlen(dev) + 1; | ||
209 | addattr_l(&req.n, sizeof(req), IFLA_IFNAME, dev, len); | ||
210 | |||
211 | // place the interface in child namespace | ||
212 | addattr_l (&req.n, sizeof(req), IFLA_NET_NS_PID, &pid, 4); | ||
213 | |||
214 | |||
215 | // add link info for the new interface | ||
216 | struct rtattr *linkinfo = NLMSG_TAIL(&req.n); | ||
217 | addattr_l(&req.n, sizeof(req), IFLA_LINKINFO, NULL, 0); | ||
218 | addattr_l(&req.n, sizeof(req), IFLA_INFO_KIND, "ipvlan", strlen("ipvlan")); | ||
219 | |||
220 | // set macvlan bridge mode | ||
221 | struct rtattr * data = NLMSG_TAIL(&req.n); | ||
222 | addattr_l(&req.n, sizeof(req), IFLA_INFO_DATA, NULL, 0); | ||
223 | int macvlan_type = IPVLAN_MODE_L2; | ||
224 | addattr_l (&req.n, sizeof(req), IFLA_INFO_KIND, &macvlan_type, 2); | ||
225 | |||
226 | data->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)data; | ||
227 | // req.n.nlmsg_len += sizeof(struct ifinfomsg); | ||
170 | 228 | ||
171 | data->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)data; | 229 | data->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)data; |
172 | linkinfo->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)linkinfo; | 230 | linkinfo->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)linkinfo; |
@@ -180,6 +238,7 @@ int net_create_macvlan(const char *dev, const char *parent, unsigned pid) { | |||
180 | return 0; | 238 | return 0; |
181 | } | 239 | } |
182 | 240 | ||
241 | |||
183 | // move the interface dev in namespace of program pid | 242 | // move the interface dev in namespace of program pid |
184 | // when the interface is moved, netlink does not preserve interface configuration | 243 | // when the interface is moved, netlink does not preserve interface configuration |
185 | int net_move_interface(const char *dev, unsigned pid) { | 244 | int net_move_interface(const char *dev, unsigned pid) { |