@@ -38,57 +38,52 @@ static const struct option_wrapper long_options[] = {
3838 {{"redirect-dev" , required_argument , NULL , 'r' },
3939 "Redirect to device <ifname>" , "<ifname>" , true},
4040
41+ {{"src-mac" , required_argument , NULL , 'L' },
42+ "Source MAC address of <dev>" , "<mac>" , true },
43+
44+ {{"dest-mac" , required_argument , NULL , 'R' },
45+ "Destination MAC address of <redirect-dev>" , "<mac>" , true },
46+
4147 {{"quiet" , no_argument , NULL , 'q' },
4248 "Quiet mode (no output)" },
4349
4450 {{0 , 0 , NULL , 0 }, NULL , false}
4551};
4652
47- static void read_output ( const char * cmd , char * str , size_t str_size )
53+ static int parse_u8 ( char * str , unsigned char * x )
4854{
49- FILE * f = popen (cmd , "r" );
50- if (!f ) {
51- fprintf (stderr , "can't execute %s" , cmd );
52- exit (EXIT_FAILURE );
53- }
55+ unsigned long z ;
5456
55- if (fgets (str , str_size , f ) == NULL ) {
56- fprintf (stderr , "can't read from popen(%s)" , cmd );
57- exit (EXIT_FAILURE );
58- }
57+ z = strtoul (str , 0 , 16 );
58+ if (z > 0xff )
59+ return -1 ;
5960
60- pclose ( f );
61- }
61+ if ( x )
62+ * x = z ;
6263
63- static void parse_mac (char * str , unsigned char mac [ETH_ALEN ])
64- {
65- mac [0 ] = strtoul (str , 0 , 16 );
66- mac [1 ] = strtoul (str + 3 , 0 , 16 );
67- mac [2 ] = strtoul (str + 6 , 0 , 16 );
68- mac [3 ] = strtoul (str + 9 , 0 , 16 );
69- mac [4 ] = strtoul (str + 12 , 0 , 16 );
70- mac [5 ] = strtoul (str + 15 , 0 , 16 );
64+ return 0 ;
7165}
7266
73- static void veth_inner_mac ( const char * ifname , unsigned char mac [ETH_ALEN ])
67+ static int parse_mac ( char * str , unsigned char mac [ETH_ALEN ])
7468{
75- char str [64 ];
76- char cmd [128 ];
77- const char * fmt = "sudo ip netns exec %s cat /sys/class/net/veth0/address" ;
69+ if (parse_u8 (str , & mac [0 ]) < 0 )
70+ return -1 ;
71+ if (parse_u8 (str + 3 , & mac [1 ]) < 0 )
72+ return -1 ;
73+ if (parse_u8 (str + 6 , & mac [2 ]) < 0 )
74+ return -1 ;
75+ if (parse_u8 (str + 9 , & mac [3 ]) < 0 )
76+ return -1 ;
77+ if (parse_u8 (str + 12 , & mac [4 ]) < 0 )
78+ return -1 ;
79+ if (parse_u8 (str + 15 , & mac [5 ]) < 0 )
80+ return -1 ;
7881
79- snprintf (cmd , sizeof (cmd ), fmt , ifname );
80- read_output (cmd , str , sizeof (str ));
81- parse_mac (str , mac );
82+ return 0 ;
8283}
8384
84- static int write_iface_params (int map_fd , struct config * cfg )
85+ static int write_iface_params (int map_fd , unsigned char * src , unsigned char * dest )
8586{
86- unsigned char src [ETH_ALEN ];
87- unsigned char dest [ETH_ALEN ];
88-
89- veth_inner_mac (cfg -> ifname , src );
90- veth_inner_mac (cfg -> redirect_ifname , dest );
91-
9287 if (bpf_map_update_elem (map_fd , src , dest , 0 ) < 0 ) {
9388 fprintf (stderr ,
9489 "WARN: Failed to update bpf map file: err(%d):%s\n" ,
@@ -138,6 +133,8 @@ int main(int argc, char **argv)
138133 int map_fd ;
139134 bool redirect_map ;
140135 char pin_dir [PATH_MAX ];
136+ unsigned char src [ETH_ALEN ];
137+ unsigned char dest [ETH_ALEN ];
141138
142139 struct config cfg = {
143140 .ifindex = -1 ,
@@ -161,6 +158,16 @@ int main(int argc, char **argv)
161158 return EXIT_FAIL_OPTION ;
162159 }
163160
161+ if (parse_mac (cfg .src_mac , src ) < 0 ) {
162+ fprintf (stderr , "ERR: can't parse mac address %s\n" , cfg .src_mac );
163+ return EXIT_FAIL_OPTION ;
164+ }
165+
166+ if (parse_mac (cfg .dest_mac , dest ) < 0 ) {
167+ fprintf (stderr , "ERR: can't parse mac address %s\n" , cfg .dest_mac );
168+ return EXIT_FAIL_OPTION ;
169+ }
170+
164171 /* Open the tx_port map corresponding to the cfg.ifname interface */
165172 map_fd = open_bpf_map_file (pin_dir , "tx_port" );
166173 if (map_fd < 0 ) {
@@ -182,7 +189,7 @@ int main(int argc, char **argv)
182189 }
183190
184191 /* Setup the mapping containing MAC addresses */
185- if (write_iface_params (map_fd , & cfg ) < 0 ) {
192+ if (write_iface_params (map_fd , src , dest ) < 0 ) {
186193 fprintf (stderr , "can't write iface params\n" );
187194 return 1 ;
188195 }
0 commit comments