11
11
12
12
#define NS_TEST "fib_lookup_ns"
13
13
#define IPV6_IFACE_ADDR "face::face"
14
+ #define IPV6_IFACE_ADDR_SEC "cafe::cafe"
15
+ #define IPV6_ADDR_DST "face::3"
14
16
#define IPV6_NUD_FAILED_ADDR "face::1"
15
17
#define IPV6_NUD_STALE_ADDR "face::2"
16
18
#define IPV4_IFACE_ADDR "10.0.0.254"
19
+ #define IPV4_IFACE_ADDR_SEC "10.1.0.254"
20
+ #define IPV4_ADDR_DST "10.2.0.254"
17
21
#define IPV4_NUD_FAILED_ADDR "10.0.0.1"
18
22
#define IPV4_NUD_STALE_ADDR "10.0.0.2"
19
23
#define IPV4_TBID_ADDR "172.0.0.254"
@@ -31,6 +35,7 @@ struct fib_lookup_test {
31
35
const char * desc ;
32
36
const char * daddr ;
33
37
int expected_ret ;
38
+ const char * expected_src ;
34
39
int lookup_flags ;
35
40
__u32 tbid ;
36
41
__u8 dmac [6 ];
@@ -69,6 +74,22 @@ static const struct fib_lookup_test tests[] = {
69
74
.daddr = IPV6_TBID_DST , .expected_ret = BPF_FIB_LKUP_RET_SUCCESS ,
70
75
.lookup_flags = BPF_FIB_LOOKUP_DIRECT | BPF_FIB_LOOKUP_TBID , .tbid = 100 ,
71
76
.dmac = DMAC_INIT2 , },
77
+ { .desc = "IPv4 set src addr from netdev" ,
78
+ .daddr = IPV4_NUD_FAILED_ADDR , .expected_ret = BPF_FIB_LKUP_RET_SUCCESS ,
79
+ .expected_src = IPV4_IFACE_ADDR ,
80
+ .lookup_flags = BPF_FIB_LOOKUP_SRC | BPF_FIB_LOOKUP_SKIP_NEIGH , },
81
+ { .desc = "IPv6 set src addr from netdev" ,
82
+ .daddr = IPV6_NUD_FAILED_ADDR , .expected_ret = BPF_FIB_LKUP_RET_SUCCESS ,
83
+ .expected_src = IPV6_IFACE_ADDR ,
84
+ .lookup_flags = BPF_FIB_LOOKUP_SRC | BPF_FIB_LOOKUP_SKIP_NEIGH , },
85
+ { .desc = "IPv4 set prefsrc addr from route" ,
86
+ .daddr = IPV4_ADDR_DST , .expected_ret = BPF_FIB_LKUP_RET_SUCCESS ,
87
+ .expected_src = IPV4_IFACE_ADDR_SEC ,
88
+ .lookup_flags = BPF_FIB_LOOKUP_SRC | BPF_FIB_LOOKUP_SKIP_NEIGH , },
89
+ { .desc = "IPv6 set prefsrc addr route" ,
90
+ .daddr = IPV6_ADDR_DST , .expected_ret = BPF_FIB_LKUP_RET_SUCCESS ,
91
+ .expected_src = IPV6_IFACE_ADDR_SEC ,
92
+ .lookup_flags = BPF_FIB_LOOKUP_SRC | BPF_FIB_LOOKUP_SKIP_NEIGH , },
72
93
};
73
94
74
95
static int ifindex ;
@@ -97,6 +118,13 @@ static int setup_netns(void)
97
118
SYS (fail , "ip neigh add %s dev veth1 nud failed" , IPV4_NUD_FAILED_ADDR );
98
119
SYS (fail , "ip neigh add %s dev veth1 lladdr %s nud stale" , IPV4_NUD_STALE_ADDR , DMAC );
99
120
121
+ /* Setup for prefsrc IP addr selection */
122
+ SYS (fail , "ip addr add %s/24 dev veth1" , IPV4_IFACE_ADDR_SEC );
123
+ SYS (fail , "ip route add %s/32 dev veth1 src %s" , IPV4_ADDR_DST , IPV4_IFACE_ADDR_SEC );
124
+
125
+ SYS (fail , "ip addr add %s/64 dev veth1 nodad" , IPV6_IFACE_ADDR_SEC );
126
+ SYS (fail , "ip route add %s/128 dev veth1 src %s" , IPV6_ADDR_DST , IPV6_IFACE_ADDR_SEC );
127
+
100
128
/* Setup for tbid lookup tests */
101
129
SYS (fail , "ip addr add %s/24 dev veth2" , IPV4_TBID_ADDR );
102
130
SYS (fail , "ip route del %s/24 dev veth2" , IPV4_TBID_NET );
@@ -133,19 +161,25 @@ static int set_lookup_params(struct bpf_fib_lookup *params, const struct fib_loo
133
161
134
162
if (inet_pton (AF_INET6 , test -> daddr , params -> ipv6_dst ) == 1 ) {
135
163
params -> family = AF_INET6 ;
136
- ret = inet_pton (AF_INET6 , IPV6_IFACE_ADDR , params -> ipv6_src );
137
- if (!ASSERT_EQ (ret , 1 , "inet_pton(IPV6_IFACE_ADDR)" ))
138
- return -1 ;
164
+ if (!(test -> lookup_flags & BPF_FIB_LOOKUP_SRC )) {
165
+ ret = inet_pton (AF_INET6 , IPV6_IFACE_ADDR , params -> ipv6_src );
166
+ if (!ASSERT_EQ (ret , 1 , "inet_pton(IPV6_IFACE_ADDR)" ))
167
+ return -1 ;
168
+ }
169
+
139
170
return 0 ;
140
171
}
141
172
142
173
ret = inet_pton (AF_INET , test -> daddr , & params -> ipv4_dst );
143
174
if (!ASSERT_EQ (ret , 1 , "convert IP[46] address" ))
144
175
return -1 ;
145
176
params -> family = AF_INET ;
146
- ret = inet_pton (AF_INET , IPV4_IFACE_ADDR , & params -> ipv4_src );
147
- if (!ASSERT_EQ (ret , 1 , "inet_pton(IPV4_IFACE_ADDR)" ))
148
- return -1 ;
177
+
178
+ if (!(test -> lookup_flags & BPF_FIB_LOOKUP_SRC )) {
179
+ ret = inet_pton (AF_INET , IPV4_IFACE_ADDR , & params -> ipv4_src );
180
+ if (!ASSERT_EQ (ret , 1 , "inet_pton(IPV4_IFACE_ADDR)" ))
181
+ return -1 ;
182
+ }
149
183
150
184
return 0 ;
151
185
}
@@ -156,6 +190,40 @@ static void mac_str(char *b, const __u8 *mac)
156
190
mac [0 ], mac [1 ], mac [2 ], mac [3 ], mac [4 ], mac [5 ]);
157
191
}
158
192
193
+ static void assert_src_ip (struct bpf_fib_lookup * fib_params , const char * expected_src )
194
+ {
195
+ int ret ;
196
+ __u32 src6 [4 ];
197
+ __be32 src4 ;
198
+
199
+ switch (fib_params -> family ) {
200
+ case AF_INET6 :
201
+ ret = inet_pton (AF_INET6 , expected_src , src6 );
202
+ ASSERT_EQ (ret , 1 , "inet_pton(expected_src)" );
203
+
204
+ ret = memcmp (src6 , fib_params -> ipv6_src , sizeof (fib_params -> ipv6_src ));
205
+ if (!ASSERT_EQ (ret , 0 , "fib_lookup ipv6 src" )) {
206
+ char str_src6 [64 ];
207
+
208
+ inet_ntop (AF_INET6 , fib_params -> ipv6_src , str_src6 ,
209
+ sizeof (str_src6 ));
210
+ printf ("ipv6 expected %s actual %s " , expected_src ,
211
+ str_src6 );
212
+ }
213
+
214
+ break ;
215
+ case AF_INET :
216
+ ret = inet_pton (AF_INET , expected_src , & src4 );
217
+ ASSERT_EQ (ret , 1 , "inet_pton(expected_src)" );
218
+
219
+ ASSERT_EQ (fib_params -> ipv4_src , src4 , "fib_lookup ipv4 src" );
220
+
221
+ break ;
222
+ default :
223
+ PRINT_FAIL ("invalid addr family: %d" , fib_params -> family );
224
+ }
225
+ }
226
+
159
227
void test_fib_lookup (void )
160
228
{
161
229
struct bpf_fib_lookup * fib_params ;
@@ -207,6 +275,9 @@ void test_fib_lookup(void)
207
275
ASSERT_EQ (skel -> bss -> fib_lookup_ret , tests [i ].expected_ret ,
208
276
"fib_lookup_ret" );
209
277
278
+ if (tests [i ].expected_src )
279
+ assert_src_ip (fib_params , tests [i ].expected_src );
280
+
210
281
ret = memcmp (tests [i ].dmac , fib_params -> dmac , sizeof (tests [i ].dmac ));
211
282
if (!ASSERT_EQ (ret , 0 , "dmac not match" )) {
212
283
char expected [18 ], actual [18 ];
0 commit comments