Skip to content

Commit 6dacb1e

Browse files
author
Octavian Purdila
committed
Merge pull request torvalds#166 from liuyuan10/arp
lkl: lkl_add_arp_entry
2 parents 0e1679b + e2a4010 commit 6dacb1e

File tree

5 files changed

+98
-2
lines changed

5 files changed

+98
-2
lines changed

Documentation/lkl.txt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,9 +189,16 @@ are the list of those variable for your environment.
189189
```
190190
$ LKL_HIJACK_NET_MTU=1280 lkl-hijack.sh ip address show
191191
```
192+
* LKL_HIJACK_NET_ARP
193+
194+
Add a list of arp permanent entries in the form of "ip|mac;ip|mac;..."
195+
```
196+
$ LKL_HIJACK_NET_ARP="192.168.13.100|12:34:56:78:9a:bc;192.168.13.101|12:34:56:78:9a:be"
197+
lkl-hijack.sh ip neighbor show
198+
```
192199
* LKL_HIJACK_DEBUG
193200

194-
increate the verbose level of debug information.
201+
increase the verbose level of debug information.
195202
```
196203
$ LKL_HIJACK_DEBUG=1 lkl-hijack.sh ip address show
197204
```

tools/lkl/include/lkl.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,14 @@ struct lkl_netdev *lkl_netdev_vde_create(const char *switch_path);
312312
*/
313313
void lkl_register_dbg_handler();
314314

315+
/**
316+
* lkl_add_arp_entry - add a permanent arp entry
317+
* @ifindex - the ifindex of the interface
318+
* @ip - ip address of the entry in network byte order
319+
* @mac - mac address of the entry
320+
*/
321+
int lkl_add_arp_entry(int ifindex, unsigned int ip, void* mac);
322+
315323
#ifdef __cplusplus
316324
}
317325
#endif

tools/lkl/lib/hijack/init.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,35 @@ int parse_mac_str(char *mac_str, __lkl__u8 mac[LKL_ETH_ALEN])
6262
return 1;
6363
}
6464

65+
/* Add permanent arp entries in the form of "ip|mac;ip|mac;..." */
66+
static void add_arp(int ifindex, char* entries) {
67+
char *saveptr = NULL, *token = NULL;
68+
char *ip = NULL, *mac_str = NULL;
69+
int ret = 0;
70+
__lkl__u8 mac[LKL_ETH_ALEN];
71+
unsigned int ip_addr;
72+
73+
for (token = strtok_r(entries, ";", &saveptr); token;
74+
token = strtok_r(NULL, ";", &saveptr)) {
75+
ip = strtok(token, "|");
76+
mac_str = strtok(NULL, "|");
77+
if (ip == NULL || mac_str == NULL || strtok(NULL, "|") != NULL) {
78+
return;
79+
}
80+
ip_addr = inet_addr(ip);
81+
ret = parse_mac_str(mac_str, mac);
82+
if (ret != 1) {
83+
fprintf(stderr, "Failed to parse mac: %s\n", mac_str);
84+
return;
85+
}
86+
ret = lkl_add_arp_entry(ifindex, ip_addr, mac);
87+
if (ret) {
88+
fprintf(stderr, "Failed to add arp entry: %s\n", lkl_strerror(ret));
89+
return;
90+
}
91+
}
92+
return;
93+
}
6594

6695
/* We don't have an easy way to make FILE*s out of our fds, so we
6796
* can't use e.g. fgets */
@@ -165,6 +194,7 @@ hijack_init(void)
165194
char *debug = getenv("LKL_HIJACK_DEBUG");
166195
char *mount = getenv("LKL_HIJACK_MOUNT");
167196
struct lkl_netdev *nd = NULL;
197+
char *arp_entries = getenv("LKL_HIJACK_NET_ARP");
168198

169199
/* Must be run before lkl_netdev_tap_create */
170200
fixup_netdev_tap_ops();
@@ -273,6 +303,9 @@ hijack_init(void)
273303

274304
if (mount)
275305
mount_cmds_exec(mount, mount_fs);
306+
307+
if (nd_ifindex >=0 && arp_entries)
308+
add_arp(nd_ifindex, arp_entries);
276309
}
277310

278311
void __attribute__((destructor))

tools/lkl/lib/net.c

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
#include "endian.h"
44
#include <lkl_host.h>
55

6-
76
static inline void set_sockaddr(struct lkl_sockaddr_in *sin, unsigned int addr,
87
unsigned short port)
98
{
@@ -159,3 +158,45 @@ int lkl_netdev_get_ifindex(int id)
159158

160159
return ret < 0 ? ret : ifr.lkl_ifr_ifindex;
161160
}
161+
162+
struct lkl_arpreq {
163+
struct lkl_sockaddr arp_pa; /* protocol address */
164+
struct lkl_sockaddr arp_ha; /* hardware address */
165+
int arp_flags; /* flags */
166+
struct lkl_sockaddr arp_netmask; /* netmask of protocol address */
167+
char arp_dev[LKL_IFNAMSIZ];
168+
};
169+
170+
#define LKL_ATF_PERM 0x04
171+
#define LKL_ATF_COM 0x02
172+
173+
int lkl_add_arp_entry(int ifindex, unsigned int ip, void* mac) {
174+
struct lkl_arpreq req;
175+
int ret = 0;
176+
struct lkl_ifreq ifr;
177+
struct lkl_sockaddr_in* sin = (struct lkl_sockaddr_in*)&req.arp_pa;
178+
int sock;
179+
180+
bzero(&req, sizeof(req));
181+
sin->sin_family = LKL_AF_INET;
182+
sin->sin_addr.lkl_s_addr = ip;
183+
memcpy(req.arp_ha.sa_data, mac, LKL_ETH_ALEN);
184+
185+
sock = lkl_sys_socket(LKL_AF_INET, LKL_SOCK_DGRAM, 0);
186+
if (sock < 0) {
187+
return sock;
188+
}
189+
190+
req.arp_flags = LKL_ATF_PERM | LKL_ATF_COM;
191+
192+
ret = ifindex_to_name(sock, &ifr, ifindex);
193+
if (ret < 0) {
194+
lkl_sys_close(sock);
195+
return ret;
196+
}
197+
strcpy(req.arp_dev, ifr.ifr_ifrn.ifrn_name);
198+
199+
ret = lkl_sys_ioctl(sock, LKL_SIOCSARP, (long)(&req));
200+
lkl_sys_close(sock);
201+
return ret;
202+
}

tools/lkl/tests/hijack-test.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,13 @@ sudo arp -d 192.168.13.2
9494
sudo ping -i 0.01 -c 65 192.168.13.2 &
9595
${hijack_script} sleep 3
9696

97+
# add arp entries
98+
ans=$(LKL_HIJACK_NET_ARP="192.168.13.100|12:34:56:78:9a:bc;192.168.13.101|12:34:56:78:9a:be"\
99+
${hijack_script} ip neighbor show) || true
100+
echo "$ans" | tail -n 15 | grep "12:34:56:78:9a:bc"
101+
echo "$ans" | tail -n 15 | grep "12:34:56:78:9a:be"
102+
103+
97104
sh ${script_dir}/run_netperf.sh 192.168.13.1 1 0 TCP_STREAM
98105
sh ${script_dir}/run_netperf.sh 192.168.13.1 1 0 TCP_RR
99106

0 commit comments

Comments
 (0)