Skip to content

Commit

Permalink
Katran reload bpf (#96)
Browse files Browse the repository at this point in the history
Summary:
this PR contains two diffs. first one revert ef8a0b3 as 2nd one allows to solve the same usecase (which is not yet implemented in that reverted diff) in more generic way.

2nd diff contains a logic to reload balancer's program in runtime w/ minimum to none disruption. it archives this by:
loading new bpf program. but for that program all maps, which were loaded/populated in original version, would be reused instead of creating a new one and populating em. e.g. by doing this we would preserv connection tracking maps and existing flow wont be affected. missed maps (e.g. the ones which exist only in new version) would be created if needed.

as a part of this logic optionally new config could be provided (e.g. if new code requires src ip to be specified and old one does not: e.g. for gue encap).

This new feature does not handle cleanup logic (e.g. if new (reloaded) balancer's code requires less maps than original one, unused maps wont be removed/freed). right now it is questionable if such ability would be useful and it is definitely would increase complexity).

Aside from reloading balancer program, it should be also reattached. so user of the library should do something like:
```
1. lb.reloadBalancerProg(path) << to reload bpf program. at this point old one is still attached, so forwarding still would be done by old bpf program.
2. lb.attachBpfProgs() << reattaching new bpf program (either to interface directly, or to the shared prog array). in both cases this (reattachment in kernel) is done under RCU/lock so it is safe to do in runtime and wont disrupt any traffic.
```

right now reloading of healthchecking program is not supported.

Note on maps renaming: libbpf's way to share map between different bpf program's requires for map's name to be no more than 15 chars. hence some names were shortened.

Some reload examples/tests:
1. original code does not have introspection enabled, but reloaded does:
```
 ./os_run_tester.sh "-reloaded_balancer_prog=/tmp/balancer_kern.o    -iobuf_storage"
+ '[' -z '' ']'
++ pwd
+ KATRAN_BUILD_DIR=/home/tehnerd/projects/sdd/projects/katran/_build/build
+ '[' -z '' ']'
++ pwd
+ DEPS_DIR=/home/tehnerd/projects/sdd/projects/katran/_build/deps
+ sudo sh -c '/home/tehnerd/projects/sdd/projects/katran/_build/build/katran/lib/testing/katran_tester -balancer_prog /home/tehnerd/projects/sdd/projects/katran/_build/deps/bpfprog/bpf/balancer_kern.o -test_from_fixtures=true -reloaded_balancer_prog=/tmp/balancer_kern.o    -iobuf_storage'
E0912 04:25:11.888264  3031 BpfLoader.cpp:94] Can't find map w/ name: lpm_src_v4
E0912 04:25:11.888324  3031 BpfLoader.cpp:94] Can't find map w/ name: decap_dst
E0912 04:25:11.888327  3031 BpfLoader.cpp:94] Can't find map w/ name: event_pipe
E0912 04:25:11.888329  3031 BpfLoader.cpp:94] Can't find map w/ name: pckt_srcs
E0912 04:25:11.888332  3031 BpfLoader.cpp:94] Can't find map w/ name: hc_pckt_srcs_map
I0912 04:25:11.888345  3031 KatranLb.cpp:717] adding new vip: 10.200.1.1:80:17
I0912 04:25:11.936579  3031 KatranLb.cpp:717] adding new vip: 10.200.1.1:80:6
I0912 04:25:11.980474  3031 KatranLb.cpp:717] adding new vip: 10.200.1.2:0:6
I0912 04:25:12.025903  3031 KatranLb.cpp:717] adding new vip: 10.200.1.4:0:6
I0912 04:25:12.071620  3031 KatranLb.cpp:821] modyfing vip: 10.200.1.4:0:6
I0912 04:25:12.071635  3031 KatranLb.cpp:717] adding new vip: 10.200.1.3:80:6
I0912 04:25:12.117257  3031 KatranLb.cpp:717] adding new vip: fc00:1::1:80:6
I0912 04:25:12.163430  3031 KatranLb.cpp:717] adding new vip: 10.200.1.5:443:17
I0912 04:25:12.163468  3031 KatranLb.cpp:821] modyfing vip: 10.200.1.5:443:17
I0912 04:25:12.209666  3031 KatranLb.cpp:717] adding new vip: fc00:1::2:443:17
I0912 04:25:12.209704  3031 KatranLb.cpp:821] modyfing vip: fc00:1::2:443:17
I0912 04:25:12.256033  3031 BpfTester.cpp:220] Test: packet to UDP based v4 VIP (and v4 real)                     result: Passed
I0912 04:25:12.256158  3031 BpfTester.cpp:220] Test: packet to TCP based v4 VIP (and v4 real)                     result: Passed
I0912 04:25:12.256224  3031 BpfTester.cpp:220] Test: packet to TCP based v4 VIP (and v4 real) + ToS in IPV4       result: Passed
I0912 04:25:12.256345  3031 BpfTester.cpp:220] Test: packet to TCP based v4 VIP (and v4 real; any dst ports).     result: Passed
I0912 04:25:12.256420  3031 BpfTester.cpp:220] Test: packet to TCP based v4 VIP (and v6 real)                     result: Passed
I0912 04:25:12.256491  3031 BpfTester.cpp:220] Test: packet to TCP based v6 VIP (and v6 real)                     result: Passed
I0912 04:25:12.256561  3031 BpfTester.cpp:220] Test: packet to TCP based v6 VIP (and v6 real) with ToS / tc set   result: Passed
I0912 04:25:12.256614  3031 BpfTester.cpp:220] Test: v4 ICMP echo-request                                         result: Passed
I0912 04:25:12.256640  3031 BpfTester.cpp:220] Test: v6 ICMP echo-request                                         result: Passed
I0912 04:25:12.256667  3031 BpfTester.cpp:220] Test: v4 ICMP dest-unreachabe fragmentation-needed                 result: Passed
I0912 04:25:12.256701  3031 BpfTester.cpp:220] Test: v6 ICMP packet-too-big                                       result: Passed
I0912 04:25:12.256772  3031 BpfTester.cpp:220] Test: drop of IPv4 packet w/ options                               result: Passed
I0912 04:25:12.256798  3031 BpfTester.cpp:220] Test: drop of IPv4 fragmented packet                               result: Passed
I0912 04:25:12.256824  3031 BpfTester.cpp:220] Test: drop of IPv6 fragmented packet                               result: Passed
I0912 04:25:12.256851  3031 BpfTester.cpp:220] Test: pass of v4 packet with dst not equal to any configured VIP   result: Passed
I0912 04:25:12.256877  3031 BpfTester.cpp:220] Test: pass of v6 packet with dst not equal to any configured VIP   result: Passed
I0912 04:25:12.256903  3031 BpfTester.cpp:220] Test: pass of arp packet                                           result: Passed
I0912 04:25:12.256932  3031 BpfTester.cpp:220] Test: LRU hit                                                      result: Passed
I0912 04:25:12.256958  3031 BpfTester.cpp:220] Test: packet #1 dst port hashing only                              result: Passed
I0912 04:25:12.256987  3031 BpfTester.cpp:220] Test: packet #2 dst port hashing only                              result: Passed
I0912 04:25:12.257014  3031 BpfTester.cpp:220] Test: ipinip packet                                                result: Passed
I0912 04:25:12.257041  3031 BpfTester.cpp:220] Test: ipv6inipv6 packet                                            result: Passed
I0912 04:25:12.257069  3031 BpfTester.cpp:220] Test: ipv4inipv6 packet                                            result: Passed
I0912 04:25:12.257097  3031 BpfTester.cpp:220] Test: QUIC: long header. Client Initial type. LRU miss             result: Passed
I0912 04:25:12.257123  3031 BpfTester.cpp:220] Test: QUIC: long header. 0-RTT Protected. CH. LRU hit.             result: Passed
I0912 04:25:12.257149  3031 BpfTester.cpp:220] Test: QUIC: long header. Handshake. v4 vip v6 real. Conn Id based. result: Passed
I0912 04:25:12.257176  3031 BpfTester.cpp:220] Test: QUIC: long header. Retry. v4 vip v6 real. Conn Id based.     result: Passed
I0912 04:25:12.257205  3031 BpfTester.cpp:220] Test: QUIC: long header. client initial. v6 vip v6 real. LRU miss  result: Passed
I0912 04:25:12.257232  3031 BpfTester.cpp:220] Test: QUIC: short header. No connection id. CH. LRU hit            result: Passed
I0912 04:25:12.257259  3031 BpfTester.cpp:220] Test: QUIC: short header w/ connection id                          result: Passed
I0912 04:25:12.257325  3031 BpfTester.cpp:220] Test: QUIC: short header w/ connection id but non-existing mapping result: Passed
I0912 04:25:12.257351  3031 BpfTester.cpp:220] Test: QUIC: short header w/ conn id. host id = 0. CH. LRU hit      result: Passed
I0912 04:25:12.257402  3031 BpfTester.cpp:220] Test: UDP: big packet of length 1515. trigger PACKET TOOBIG        result: Passed
I0912 04:25:12.257406  3031 katran_tester.cpp:257] Testing counter's sanity. Printing on errors only
I0912 04:25:12.257494  3031 katran_tester.cpp:313] Testing of counters is complete
E0912 04:25:12.257956  3031 KatranSimulator.cpp:168] src and dst must have same address family
E0912 04:25:12.257961  3031 KatranSimulator.cpp:161] malformed src or dst ip address. src: aaaa dst: bbbb

I0912 04:25:12.257963  3031 katran_tester.cpp:337] Test katran monitor.    <<<< NOTHING HERE. AS INTROSPECTION IS NOT ENABLED FOR ORIGINAL VERSION

E0912 04:25:13.258879  3031 BpfLoader.cpp:104] Can't find prog with name: cls-hc
I0912 04:25:13.258942  3031 katran_tester.cpp:179] Healthchecking not enabled. Skipping HC related tests
libbpf: Error in bpf_create_map_xattr(event_pipe):ERROR: strerror_r(-524)=22(-524). Retrying without BTF.
E0912 04:25:13.292759  3031 BpfLoader.cpp:94] Can't find map w/ name: lpm_src_v4
E0912 04:25:13.292776  3031 BpfLoader.cpp:94] Can't find map w/ name: decap_dst
E0912 04:25:13.292783  3031 BpfLoader.cpp:94] Can't find map w/ name: pckt_srcs
E0912 04:25:13.292788  3031 BpfLoader.cpp:94] Can't find map w/ name: hc_pckt_srcs_map
I0912 04:25:13.293278  3031 KatranLb.cpp:717] adding new vip: 10.200.1.1:80:17
I0912 04:25:13.293290  3031 KatranLb.cpp:725] trying to add already existing vip
I0912 04:25:13.293299  3031 KatranLb.cpp:717] adding new vip: 10.200.1.1:80:6
I0912 04:25:13.293303  3031 KatranLb.cpp:725] trying to add already existing vip
I0912 04:25:13.293306  3031 KatranLb.cpp:717] adding new vip: 10.200.1.2:0:6
I0912 04:25:13.293309  3031 KatranLb.cpp:725] trying to add already existing vip
I0912 04:25:13.293313  3031 KatranLb.cpp:717] adding new vip: 10.200.1.4:0:6
I0912 04:25:13.293320  3031 KatranLb.cpp:725] trying to add already existing vip
I0912 04:25:13.293329  3031 KatranLb.cpp:821] modyfing vip: 10.200.1.4:0:6
I0912 04:25:13.293337  3031 KatranLb.cpp:717] adding new vip: 10.200.1.3:80:6
I0912 04:25:13.293341  3031 KatranLb.cpp:725] trying to add already existing vip
I0912 04:25:13.293349  3031 KatranLb.cpp:717] adding new vip: fc00:1::1:80:6
I0912 04:25:13.293354  3031 KatranLb.cpp:725] trying to add already existing vip
I0912 04:25:13.293359  3031 KatranLb.cpp:1456] trying to add already existing mapping for 10.0.0.1
I0912 04:25:13.293365  3031 KatranLb.cpp:1456] trying to add already existing mapping for 10.0.0.2
I0912 04:25:13.293368  3031 KatranLb.cpp:1456] trying to add already existing mapping for 10.0.0.3
I0912 04:25:13.293372  3031 KatranLb.cpp:1456] trying to add already existing mapping for fc00::1
I0912 04:25:13.293377  3031 KatranLb.cpp:1456] trying to add already existing mapping for fc00::2
I0912 04:25:13.293381  3031 KatranLb.cpp:1456] trying to add already existing mapping for fc00::3
I0912 04:25:13.293385  3031 KatranLb.cpp:717] adding new vip: 10.200.1.5:443:17
I0912 04:25:13.293390  3031 KatranLb.cpp:725] trying to add already existing vip
I0912 04:25:13.293392  3031 KatranLb.cpp:821] modyfing vip: 10.200.1.5:443:17
I0912 04:25:13.293399  3031 KatranLb.cpp:717] adding new vip: fc00:1::2:443:17
I0912 04:25:13.293403  3031 KatranLb.cpp:725] trying to add already existing vip
I0912 04:25:13.293407  3031 KatranLb.cpp:821] modyfing vip: fc00:1::2:443:17
I0912 04:25:13.293608  3031 BpfTester.cpp:220] Test: packet to UDP based v4 VIP (and v4 real)                     result: Passed
I0912 04:25:13.293678  3031 BpfTester.cpp:220] Test: packet to TCP based v4 VIP (and v4 real)                     result: Passed
I0912 04:25:13.293714  3031 BpfTester.cpp:220] Test: packet to TCP based v4 VIP (and v4 real) + ToS in IPV4       result: Passed
I0912 04:25:13.293747  3031 BpfTester.cpp:220] Test: packet to TCP based v4 VIP (and v4 real; any dst ports).     result: Passed
I0912 04:25:13.293783  3031 BpfTester.cpp:220] Test: packet to TCP based v4 VIP (and v6 real)                     result: Passed
I0912 04:25:13.293820  3031 BpfTester.cpp:220] Test: packet to TCP based v6 VIP (and v6 real)                     result: Passed
I0912 04:25:13.293856  3031 BpfTester.cpp:220] Test: packet to TCP based v6 VIP (and v6 real) with ToS / tc set   result: Passed
I0912 04:25:13.293889  3031 BpfTester.cpp:220] Test: v4 ICMP echo-request                                         result: Passed
I0912 04:25:13.293923  3031 BpfTester.cpp:220] Test: v6 ICMP echo-request                                         result: Passed
I0912 04:25:13.293959  3031 BpfTester.cpp:220] Test: v4 ICMP dest-unreachabe fragmentation-needed                 result: Passed
I0912 04:25:13.293995  3031 BpfTester.cpp:220] Test: v6 ICMP packet-too-big                                       result: Passed
I0912 04:25:13.294030  3031 BpfTester.cpp:220] Test: drop of IPv4 packet w/ options                               result: Passed
I0912 04:25:13.294064  3031 BpfTester.cpp:220] Test: drop of IPv4 fragmented packet                               result: Passed
I0912 04:25:13.294096  3031 BpfTester.cpp:220] Test: drop of IPv6 fragmented packet                               result: Passed
I0912 04:25:13.294131  3031 BpfTester.cpp:220] Test: pass of v4 packet with dst not equal to any configured VIP   result: Passed
I0912 04:25:13.294165  3031 BpfTester.cpp:220] Test: pass of v6 packet with dst not equal to any configured VIP   result: Passed
I0912 04:25:13.294199  3031 BpfTester.cpp:220] Test: pass of arp packet                                           result: Passed
I0912 04:25:13.294234  3031 BpfTester.cpp:220] Test: LRU hit                                                      result: Passed
I0912 04:25:13.294315  3031 BpfTester.cpp:220] Test: packet #1 dst port hashing only                              result: Passed
I0912 04:25:13.294358  3031 BpfTester.cpp:220] Test: packet #2 dst port hashing only                              result: Passed
I0912 04:25:13.294399  3031 BpfTester.cpp:220] Test: ipinip packet                                                result: Passed
I0912 04:25:13.294474  3031 BpfTester.cpp:220] Test: ipv6inipv6 packet                                            result: Passed
I0912 04:25:13.294514  3031 BpfTester.cpp:220] Test: ipv4inipv6 packet                                            result: Passed
I0912 04:25:13.294555  3031 BpfTester.cpp:220] Test: QUIC: long header. Client Initial type. LRU miss             result: Passed
I0912 04:25:13.294595  3031 BpfTester.cpp:220] Test: QUIC: long header. 0-RTT Protected. CH. LRU hit.             result: Passed
I0912 04:25:13.294633  3031 BpfTester.cpp:220] Test: QUIC: long header. Handshake. v4 vip v6 real. Conn Id based. result: Passed
I0912 04:25:13.294672  3031 BpfTester.cpp:220] Test: QUIC: long header. Retry. v4 vip v6 real. Conn Id based.     result: Passed
I0912 04:25:13.294713  3031 BpfTester.cpp:220] Test: QUIC: long header. client initial. v6 vip v6 real. LRU miss  result: Passed
I0912 04:25:13.294751  3031 BpfTester.cpp:220] Test: QUIC: short header. No connection id. CH. LRU hit            result: Passed
I0912 04:25:13.294791  3031 BpfTester.cpp:220] Test: QUIC: short header w/ connection id                          result: Passed
I0912 04:25:13.294831  3031 BpfTester.cpp:220] Test: QUIC: short header w/ connection id but non-existing mapping result: Passed
I0912 04:25:13.294868  3031 BpfTester.cpp:220] Test: QUIC: short header w/ conn id. host id = 0. CH. LRU hit      result: Passed
I0912 04:25:13.294950  3031 BpfTester.cpp:220] Test: UDP: big packet of length 1515. trigger PACKET TOOBIG        result: Passed
I0912 04:25:13.294958  3031 katran_tester.cpp:257] Testing counter's sanity. Printing on errors only
I0912 04:25:13.294987  3031 katran_tester.cpp:261] per Vip counter is incorrect for vip:10.200.1.1
I0912 04:25:13.295011  3031 katran_tester.cpp:266] LRU counter is incorrect
I0912 04:25:13.295030  3031 katran_tester.cpp:271] per pckt type LRU miss counter is incorrect
I0912 04:25:13.295051  3031 katran_tester.cpp:276] LRU fallback counter is incorrect
I0912 04:25:13.295070  3031 katran_tester.cpp:280] Counters for QUIC packets routed with CH: 10,  with connection-id: 8
I0912 04:25:13.295078  3031 katran_tester.cpp:282] Counters for routing of QUIC packets is wrong.
I0912 04:25:13.295100  3031 katran_tester.cpp:296] incorrect stats for real: 10.0.0.1
I0912 04:25:13.295109  3031 katran_tester.cpp:297] Expected to be incorrect w/ non default build flags
I0912 04:25:13.295128  3031 katran_tester.cpp:296] incorrect stats for real: 10.0.0.2
I0912 04:25:13.295136  3031 katran_tester.cpp:297] Expected to be incorrect w/ non default build flags
I0912 04:25:13.295156  3031 katran_tester.cpp:296] incorrect stats for real: 10.0.0.3
I0912 04:25:13.295164  3031 katran_tester.cpp:297] Expected to be incorrect w/ non default build flags
I0912 04:25:13.295186  3031 katran_tester.cpp:296] incorrect stats for real: fc00::1
I0912 04:25:13.295193  3031 katran_tester.cpp:297] Expected to be incorrect w/ non default build flags
I0912 04:25:13.295213  3031 katran_tester.cpp:296] incorrect stats for real: fc00::2
I0912 04:25:13.295222  3031 katran_tester.cpp:297] Expected to be incorrect w/ non default build flags
I0912 04:25:13.295243  3031 katran_tester.cpp:296] incorrect stats for real: fc00::3
I0912 04:25:13.295250  3031 katran_tester.cpp:297] Expected to be incorrect w/ non default build flags
I0912 04:25:13.295255  3031 katran_tester.cpp:313] Testing of counters is complete
E0912 04:25:13.295521  3031 KatranSimulator.cpp:168] src and dst must have same address family
E0912 04:25:13.295527  3031 KatranSimulator.cpp:161] malformed src or dst ip address. src: aaaa dst: bbbb

I0912 04:25:13.295531  3031 katran_tester.cpp:337] Test katran monitor <<< RELOADED VERSION CONTAINS INTROSPECTION. SOME DATA ABOUT PACKETS WERE SENT THROUGH PERF PIPE

I0912 04:25:14.296711  3031 katran_tester.cpp:167] buffer length is: 194
I0912 04:25:14.296993  3031 katran_tester.cpp:167] buffer length is: 168
E0912 04:25:14.297132  3031 BpfLoader.cpp:104] Can't find prog with name: cls-hc
I0912 04:25:14.297152  3031 katran_tester.cpp:179] Healthchecking not enabled. Skipping HC related tests
```

another example balancer without gue vs w/ gue encap.

```
./os_run_tester.sh "-reloaded_balancer_prog=/tmp/balancer_kern.o    -gue"
+ '[' -z '' ']'
++ pwd
+ KATRAN_BUILD_DIR=/home/tehnerd/projects/sdd/projects/katran/_build/build
+ '[' -z '' ']'
++ pwd
+ DEPS_DIR=/home/tehnerd/projects/sdd/projects/katran/_build/deps
+ sudo sh -c '/home/tehnerd/projects/sdd/projects/katran/_build/build/katran/lib/testing/katran_tester -balancer_prog /home/tehnerd/projects/sdd/projects/katran/_build/deps/bpfprog/bpf/balancer_kern.o -test_from_fixtures=true -reloaded_balancer_prog=/tmp/balancer_kern.o    -gue'
E0912 04:31:14.927762  3131 BpfLoader.cpp:94] Can't find map w/ name: lpm_src_v4
E0912 04:31:14.927841  3131 BpfLoader.cpp:94] Can't find map w/ name: decap_dst
E0912 04:31:14.927852  3131 BpfLoader.cpp:94] Can't find map w/ name: event_pipe
E0912 04:31:14.927856  3131 BpfLoader.cpp:94] Can't find map w/ name: pckt_srcs
E0912 04:31:14.927861  3131 BpfLoader.cpp:94] Can't find map w/ name: hc_pckt_srcs_map
I0912 04:31:14.927877  3131 KatranLb.cpp:717] adding new vip: 10.200.1.1:80:17
I0912 04:31:14.976330  3131 KatranLb.cpp:717] adding new vip: 10.200.1.1:80:6
I0912 04:31:15.021167  3131 KatranLb.cpp:717] adding new vip: 10.200.1.2:0:6
I0912 04:31:15.067157  3131 KatranLb.cpp:717] adding new vip: 10.200.1.4:0:6
I0912 04:31:15.113668  3131 KatranLb.cpp:821] modyfing vip: 10.200.1.4:0:6
I0912 04:31:15.113682  3131 KatranLb.cpp:717] adding new vip: 10.200.1.3:80:6
I0912 04:31:15.160688  3131 KatranLb.cpp:717] adding new vip: fc00:1::1:80:6
I0912 04:31:15.207733  3131 KatranLb.cpp:717] adding new vip: 10.200.1.5:443:17
I0912 04:31:15.207773  3131 KatranLb.cpp:821] modyfing vip: 10.200.1.5:443:17
I0912 04:31:15.255038  3131 KatranLb.cpp:717] adding new vip: fc00:1::2:443:17
I0912 04:31:15.255079  3131 KatranLb.cpp:821] modyfing vip: fc00:1::2:443:17

MOST OF THE TESTS FAILED

I0912 04:31:15.302585  3131 BpfTester.cpp:220] Test: packet to UDP based v4 VIP (and v4 real)                     result: Failed
I0912 04:31:15.302676  3131 BpfTester.cpp:220] Test: packet to TCP based v4 VIP (and v4 real)                     result: Failed
I0912 04:31:15.302933  3131 BpfTester.cpp:220] Test: packet to TCP based v4 VIP (and v4 real; any dst ports).     result: Failed
I0912 04:31:15.303011  3131 BpfTester.cpp:220] Test: packet to TCP based v4 VIP (and v6 real)                     result: Failed
I0912 04:31:15.303089  3131 BpfTester.cpp:220] Test: packet to TCP based v6 VIP (and v6 real)                     result: Failed
I0912 04:31:15.303159  3131 BpfTester.cpp:220] Test: v4 ICMP echo-request                                         result: Passed
I0912 04:31:15.303215  3131 BpfTester.cpp:220] Test: v6 ICMP echo-request                                         result: Passed
I0912 04:31:15.303270  3131 BpfTester.cpp:220] Test: v4 ICMP dest-unreachabe fragmentation-needed                 result: Failed
I0912 04:31:15.303301  3131 BpfTester.cpp:220] Test: v6 ICMP packet-too-big                                       result: Failed
I0912 04:31:15.303329  3131 BpfTester.cpp:220] Test: drop of IPv4 packet w/ options                               result: Passed
I0912 04:31:15.303357  3131 BpfTester.cpp:220] Test: drop of IPv4 fragmented packet                               result: Passed
I0912 04:31:15.303386  3131 BpfTester.cpp:220] Test: drop of IPv6 fragmented packet                               result: Passed
I0912 04:31:15.303414  3131 BpfTester.cpp:220] Test: pass of v4 packet with dst not equal to any configured VIP   result: Passed
I0912 04:31:15.303443  3131 BpfTester.cpp:220] Test: pass of v6 packet with dst not equal to any configured VIP   result: Passed
I0912 04:31:15.303472  3131 BpfTester.cpp:220] Test: pass of arp packet                                           result: Passed
I0912 04:31:15.303501  3131 BpfTester.cpp:220] Test: LRU hit                                                      result: Failed
I0912 04:31:15.303530  3131 BpfTester.cpp:220] Test: packet #1 dst port hashing only                              result: Failed
I0912 04:31:15.303560  3131 BpfTester.cpp:220] Test: packet #2 dst port hashing only                              result: Failed
I0912 04:31:15.303587  3131 BpfTester.cpp:220] Test: gue ipv4 inner ipv4 outer packet                             result: Passed
I0912 04:31:15.303613  3131 BpfTester.cpp:220] Test: gue ipv6 inner ipv6 outer packet                             result: Passed
I0912 04:31:15.303651  3131 BpfTester.cpp:220] Test: gue ipv4 inner ipv6 outer packet                             result: Passed
I0912 04:31:15.303678  3131 BpfTester.cpp:220] Test: QUIC: long header. Client Initial type. LRU miss             result: Failed
I0912 04:31:15.303707  3131 BpfTester.cpp:220] Test: QUIC: long header. 0-RTT Protected. CH. LRU hit.             result: Failed
I0912 04:31:15.303735  3131 BpfTester.cpp:220] Test: QUIC: long header. Handshake. v4 vip v6 real. Conn Id based. result: Failed
I0912 04:31:15.303761  3131 BpfTester.cpp:220] Test: QUIC: long header. Retry. v4 vip v6 real. Conn Id based.     result: Failed
I0912 04:31:15.303786  3131 BpfTester.cpp:220] Test: QUIC: long header. client initial. v6 vip v6 real. LRU miss  result: Failed
I0912 04:31:15.303812  3131 BpfTester.cpp:220] Test: QUIC: short header. No connection id. CH. LRU hit            result: Failed
I0912 04:31:15.303839  3131 BpfTester.cpp:220] Test: QUIC: short header w/ connection id                          result: Failed
I0912 04:31:15.303867  3131 BpfTester.cpp:220] Test: QUIC: short header w/ connection id but non-existing mapping result: Failed
I0912 04:31:15.303892  3131 BpfTester.cpp:220] Test: QUIC: short header w/ conn id. host id = 0. CH. LRU hit      result: Failed
I0912 04:31:15.303918  3131 BpfTester.cpp:220] Test: packet to TCP based v4 VIP (and v4 real) + ToS in IPV4       result: Failed
I0912 04:31:15.303946  3131 BpfTester.cpp:220] Test: packet to TCP based v6 VIP (and v6 real) with ToS / tc set   result: Failed
I0912 04:31:15.303949  3131 katran_tester.cpp:257] Testing counter's sanity. Printing on errors only
I0912 04:31:15.304035  3131 katran_tester.cpp:313] Testing of counters is complete
E0912 04:31:15.304160  3131 KatranSimulator.cpp:168] src and dst must have same address family
E0912 04:31:15.304165  3131 KatranSimulator.cpp:161] malformed src or dst ip address. src: aaaa dst: bbbb
E0912 04:31:15.304169  3131 BpfLoader.cpp:104] Can't find prog with name: cls-hc
I0912 04:31:15.304173  3131 katran_tester.cpp:179] Healthchecking not enabled. Skipping HC related tests
E0912 04:31:15.307870  3131 BpfLoader.cpp:94] Can't find map w/ name: lpm_src_v4
E0912 04:31:15.307879  3131 BpfLoader.cpp:94] Can't find map w/ name: decap_dst
E0912 04:31:15.307884  3131 BpfLoader.cpp:94] Can't find map w/ name: event_pipe
E0912 04:31:15.307891  3131 BpfLoader.cpp:94] Can't find map w/ name: hc_pckt_srcs_map
I0912 04:31:15.307900  3131 KatranLb.cpp:717] adding new vip: 10.200.1.1:80:17
I0912 04:31:15.307905  3131 KatranLb.cpp:725] trying to add already existing vip
I0912 04:31:15.307911  3131 KatranLb.cpp:717] adding new vip: 10.200.1.1:80:6
I0912 04:31:15.307914  3131 KatranLb.cpp:725] trying to add already existing vip
I0912 04:31:15.307919  3131 KatranLb.cpp:717] adding new vip: 10.200.1.2:0:6
I0912 04:31:15.307922  3131 KatranLb.cpp:725] trying to add already existing vip
I0912 04:31:15.307926  3131 KatranLb.cpp:717] adding new vip: 10.200.1.4:0:6
I0912 04:31:15.307929  3131 KatranLb.cpp:725] trying to add already existing vip
I0912 04:31:15.307934  3131 KatranLb.cpp:821] modyfing vip: 10.200.1.4:0:6
I0912 04:31:15.307940  3131 KatranLb.cpp:717] adding new vip: 10.200.1.3:80:6
I0912 04:31:15.307943  3131 KatranLb.cpp:725] trying to add already existing vip
I0912 04:31:15.307950  3131 KatranLb.cpp:717] adding new vip: fc00:1::1:80:6
I0912 04:31:15.307955  3131 KatranLb.cpp:725] trying to add already existing vip
I0912 04:31:15.307960  3131 KatranLb.cpp:1456] trying to add already existing mapping for 10.0.0.1
I0912 04:31:15.307965  3131 KatranLb.cpp:1456] trying to add already existing mapping for 10.0.0.2
I0912 04:31:15.307968  3131 KatranLb.cpp:1456] trying to add already existing mapping for 10.0.0.3
I0912 04:31:15.307972  3131 KatranLb.cpp:1456] trying to add already existing mapping for fc00::1
I0912 04:31:15.307976  3131 KatranLb.cpp:1456] trying to add already existing mapping for fc00::2
I0912 04:31:15.307979  3131 KatranLb.cpp:1456] trying to add already existing mapping for fc00::3
I0912 04:31:15.307982  3131 KatranLb.cpp:717] adding new vip: 10.200.1.5:443:17
I0912 04:31:15.307986  3131 KatranLb.cpp:725] trying to add already existing vip
I0912 04:31:15.307988  3131 KatranLb.cpp:821] modyfing vip: 10.200.1.5:443:17
I0912 04:31:15.307994  3131 KatranLb.cpp:717] adding new vip: fc00:1::2:443:17
I0912 04:31:15.307997  3131 KatranLb.cpp:725] trying to add already existing vip
I0912 04:31:15.308001  3131 KatranLb.cpp:821] modyfing vip: fc00:1::2:443:17

ALL TESTS PASSED

I0912 04:31:15.308081  3131 BpfTester.cpp:220] Test: packet to UDP based v4 VIP (and v4 real)                     result: Passed
I0912 04:31:15.308329  3131 BpfTester.cpp:220] Test: packet to TCP based v4 VIP (and v4 real)                     result: Passed
I0912 04:31:15.308414  3131 BpfTester.cpp:220] Test: packet to TCP based v4 VIP (and v4 real; any dst ports).     result: Passed
I0912 04:31:15.308488  3131 BpfTester.cpp:220] Test: packet to TCP based v4 VIP (and v6 real)                     result: Passed
I0912 04:31:15.308558  3131 BpfTester.cpp:220] Test: packet to TCP based v6 VIP (and v6 real)                     result: Passed
I0912 04:31:15.308648  3131 BpfTester.cpp:220] Test: v4 ICMP echo-request                                         result: Passed
I0912 04:31:15.308672  3131 BpfTester.cpp:220] Test: v6 ICMP echo-request                                         result: Passed
I0912 04:31:15.308696  3131 BpfTester.cpp:220] Test: v4 ICMP dest-unreachabe fragmentation-needed                 result: Passed
I0912 04:31:15.308723  3131 BpfTester.cpp:220] Test: v6 ICMP packet-too-big                                       result: Passed
I0912 04:31:15.308750  3131 BpfTester.cpp:220] Test: drop of IPv4 packet w/ options                               result: Passed
I0912 04:31:15.308773  3131 BpfTester.cpp:220] Test: drop of IPv4 fragmented packet                               result: Passed
I0912 04:31:15.308799  3131 BpfTester.cpp:220] Test: drop of IPv6 fragmented packet                               result: Passed
I0912 04:31:15.308822  3131 BpfTester.cpp:220] Test: pass of v4 packet with dst not equal to any configured VIP   result: Passed
I0912 04:31:15.308852  3131 BpfTester.cpp:220] Test: pass of v6 packet with dst not equal to any configured VIP   result: Passed
I0912 04:31:15.308881  3131 BpfTester.cpp:220] Test: pass of arp packet                                           result: Passed
I0912 04:31:15.308902  3131 BpfTester.cpp:220] Test: LRU hit                                                      result: Passed
I0912 04:31:15.308929  3131 BpfTester.cpp:220] Test: packet #1 dst port hashing only                              result: Passed
I0912 04:31:15.308954  3131 BpfTester.cpp:220] Test: packet #2 dst port hashing only                              result: Passed
I0912 04:31:15.308977  3131 BpfTester.cpp:220] Test: gue ipv4 inner ipv4 outer packet                             result: Passed
I0912 04:31:15.309006  3131 BpfTester.cpp:220] Test: gue ipv6 inner ipv6 outer packet                             result: Passed
I0912 04:31:15.309032  3131 BpfTester.cpp:220] Test: gue ipv4 inner ipv6 outer packet                             result: Passed
I0912 04:31:15.309060  3131 BpfTester.cpp:220] Test: QUIC: long header. Client Initial type. LRU miss             result: Passed
I0912 04:31:15.309085  3131 BpfTester.cpp:220] Test: QUIC: long header. 0-RTT Protected. CH. LRU hit.             result: Passed
I0912 04:31:15.309108  3131 BpfTester.cpp:220] Test: QUIC: long header. Handshake. v4 vip v6 real. Conn Id based. result: Passed
I0912 04:31:15.309135  3131 BpfTester.cpp:220] Test: QUIC: long header. Retry. v4 vip v6 real. Conn Id based.     result: Passed
I0912 04:31:15.309167  3131 BpfTester.cpp:220] Test: QUIC: long header. client initial. v6 vip v6 real. LRU miss  result: Passed
I0912 04:31:15.309195  3131 BpfTester.cpp:220] Test: QUIC: short header. No connection id. CH. LRU hit            result: Passed
I0912 04:31:15.309217  3131 BpfTester.cpp:220] Test: QUIC: short header w/ connection id                          result: Passed
I0912 04:31:15.309243  3131 BpfTester.cpp:220] Test: QUIC: short header w/ connection id but non-existing mapping result: Passed
I0912 04:31:15.309267  3131 BpfTester.cpp:220] Test: QUIC: short header w/ conn id. host id = 0. CH. LRU hit      result: Passed
I0912 04:31:15.309290  3131 BpfTester.cpp:220] Test: packet to TCP based v4 VIP (and v4 real) + ToS in IPV4       result: Passed
I0912 04:31:15.309319  3131 BpfTester.cpp:220] Test: packet to TCP based v6 VIP (and v6 real) with ToS / tc set   result: Passed
I0912 04:31:15.309324  3131 katran_tester.cpp:257] Testing counter's sanity. Printing on errors only
I0912 04:31:15.309350  3131 katran_tester.cpp:261] per Vip counter is incorrect for vip:10.200.1.1
I0912 04:31:15.309361  3131 katran_tester.cpp:266] LRU counter is incorrect
I0912 04:31:15.309371  3131 katran_tester.cpp:271] per pckt type LRU miss counter is incorrect
I0912 04:31:15.309381  3131 katran_tester.cpp:276] LRU fallback counter is incorrect
I0912 04:31:15.309391  3131 katran_tester.cpp:280] Counters for QUIC packets routed with CH: 10,  with connection-id: 8
I0912 04:31:15.309394  3131 katran_tester.cpp:282] Counters for routing of QUIC packets is wrong.
I0912 04:31:15.309406  3131 katran_tester.cpp:296] incorrect stats for real: 10.0.0.1
I0912 04:31:15.309410  3131 katran_tester.cpp:297] Expected to be incorrect w/ non default build flags
I0912 04:31:15.309418  3131 katran_tester.cpp:296] incorrect stats for real: 10.0.0.2
I0912 04:31:15.309422  3131 katran_tester.cpp:297] Expected to be incorrect w/ non default build flags
I0912 04:31:15.309429  3131 katran_tester.cpp:296] incorrect stats for real: 10.0.0.3
I0912 04:31:15.309432  3131 katran_tester.cpp:297] Expected to be incorrect w/ non default build flags
I0912 04:31:15.309442  3131 katran_tester.cpp:296] incorrect stats for real: fc00::1
I0912 04:31:15.309444  3131 katran_tester.cpp:297] Expected to be incorrect w/ non default build flags
I0912 04:31:15.309453  3131 katran_tester.cpp:296] incorrect stats for real: fc00::2
I0912 04:31:15.309455  3131 katran_tester.cpp:297] Expected to be incorrect w/ non default build flags
I0912 04:31:15.309463  3131 katran_tester.cpp:296] incorrect stats for real: fc00::3
I0912 04:31:15.309466  3131 katran_tester.cpp:297] Expected to be incorrect w/ non default build flags
I0912 04:31:15.309469  3131 katran_tester.cpp:313] Testing of counters is complete
E0912 04:31:15.309583  3131 KatranSimulator.cpp:168] src and dst must have same address family
E0912 04:31:15.309588  3131 KatranSimulator.cpp:161] malformed src or dst ip address. src: aaaa dst: bbbb
E0912 04:31:15.309595  3131 BpfLoader.cpp:104] Can't find prog with name: cls-hc
I0912 04:31:15.309599  3131 katran_tester.cpp:179] Healthchecking not enabled. Skipping HC related tests
```

Pull Request resolved: #96

Reviewed By: xttjsn

Differential Revision: D23674803

Pulled By: udippant

fbshipit-source-id: 3e93c42f97e5559258d87fa9ba0e47d8d52f5349
  • Loading branch information
tehnerd authored and facebook-github-bot committed Sep 21, 2020
1 parent 83f01c5 commit d195c04
Show file tree
Hide file tree
Showing 15 changed files with 288 additions and 62 deletions.
10 changes: 7 additions & 3 deletions build_bpf_modules_opensource.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,25 @@ set -xeo pipefail
usage() {
cat 1>&2 <<EOF
Usage ${0##*/} [-h|?] [-s SRC_DIR] [-b BUILD_DIR]
Usage ${0##*/} [-h|?] [-s SRC_DIR] [-b BUILD_DIR] [-d DEFINES]
-s SRC_DIR (optional): Path to source dir for katran
-b BUILD_DIR (optional): Path to build dir for katran
-d DEFINES (optional): Specify custom defines for bpf program
-h|? Show this help message
EOF
}

while getopts ":hb:s:m" arg; do
while getopts ":hb:s:d:m" arg; do
case $arg in
b)
BUILD_DIR="${OPTARG}"
;;
s)
SRC_DIR="${OPTARG}"
;;
d)
DEFINES="${OPTARG}"
;;
h) # Display help.
usage
exit 0
Expand Down Expand Up @@ -74,6 +78,6 @@ cp -r "${SRC_DIR}/katran/lib/bpf" "${BUILD_DIR}/deps/bpfprog/"
cp -r "${SRC_DIR}/katran/decap/bpf" "${BUILD_DIR}/deps/bpfprog/"
cp "${SRC_DIR}"/katran/lib/linux_includes/* "${BUILD_DIR}/deps/bpfprog/include/"
cd "${BUILD_DIR}/deps/bpfprog" && LD_LIBRARY_PATH="${CLANG_PATH}/lib" make \
EXTRA_CFLAGS="$*" \
EXTRA_CFLAGS="${DEFINES}" \
LLC="${CLANG_PATH}/bin/llc" CLANG="${CLANG_PATH}/bin/clang"
echo "BPF BUILD COMPLITED"
6 changes: 6 additions & 0 deletions katran/lib/BpfAdapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,12 @@ int BpfAdapter::loadBpfProg(
return loader_.loadBpfFile(bpf_prog, type, use_names);
}

int BpfAdapter::reloadBpfProg(
const std::string& bpf_prog,
const bpf_prog_type type) {
return loader_.reloadBpfFromFile(bpf_prog, type);
}

int BpfAdapter::loadBpfProg(
char* buf,
int buf_size,
Expand Down
14 changes: 14 additions & 0 deletions katran/lib/BpfAdapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,20 @@ class BpfAdapter {
const bpf_prog_type type = BPF_PROG_TYPE_UNSPEC,
bool use_names = false);

/**
* @param string bpf_prog path to bpf program
* @param bpf_prog_type type of bpf prog to load
* @return int result 0 in case of success, other val otherwise
*
* helper function to reload bpf program into the kernel
* loader could either deduct type from prog's name
* (supported xdp- and cls- prefixes) or by using option
* bpf_prog_type hint
*/
int reloadBpfProg(
const std::string& bpf_prog,
const bpf_prog_type type = BPF_PROG_TYPE_UNSPEC);

/**
* @param char* ptr to buffer with bpf's elf object
* @param int size of the buffer
Expand Down
115 changes: 110 additions & 5 deletions katran/lib/BpfLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ ::bpf_prog_type normalizeBpfProgType(
if (type != BPF_PROG_TYPE_UNSPEC) {
return type;
}
std::string prog_name(::bpf_program__title(prog, false));
std::string prog_name(::bpf_program__section_name(prog));
auto prefix = prog_name.substr(kStart, kPrefixLen);
if (prefix == "xdp") {
VLOG(2) << "prog " << prog_name << " type: XDP";
Expand Down Expand Up @@ -135,6 +135,16 @@ int BpfLoader::loadBpfFile(
return loadBpfObject(obj, path, type);
}

int BpfLoader::reloadBpfFromFile(
const std::string& path,
const bpf_prog_type type) {
auto obj = ::bpf_object__open(path.c_str());
if (obj == nullptr) {
return kError;
}
return reloadBpfObject(obj, path, type);
}

int BpfLoader::loadBpfFromBuffer(
char* buf,
int buf_size,
Expand All @@ -147,6 +157,101 @@ int BpfLoader::loadBpfFromBuffer(
return loadBpfObject(obj, "buffer", type);
}

int BpfLoader::reloadBpfObject(
::bpf_object* obj,
const std::string& name,
const bpf_prog_type type) {
::bpf_program* prog;
::bpf_map* map;

bpf_object__for_each_program(prog, obj) {
// reload bpf program only if we have loaded it already. we distinct bpf
// programs by their name
if (progs_.find(::bpf_program__section_name(prog)) == progs_.end()) {
LOG(ERROR) << "trying to reload not yet loaded program: "
<< ::bpf_program__section_name(prog);
return closeBpfObject(obj);
}
auto prog_type = normalizeBpfProgType(prog, type);
::bpf_program__set_type(prog, prog_type);
}

bpf_map__for_each(map, obj) {
auto map_name = ::bpf_map__name(map);
auto shared_map_iter = sharedMaps_.find(map_name);
if (shared_map_iter != sharedMaps_.end()) {
VLOG(2) << "shared map found w/ a name: " << shared_map_iter->first
<< " fd: " << shared_map_iter->second;
if (::bpf_map__reuse_fd(map, shared_map_iter->second)) {
LOG(ERROR) << "error while trying to set fd of shared map: "
<< shared_map_iter->first;
return closeBpfObject(obj);
}
continue;
}

auto map_iter = maps_.find(map_name);
if (map_iter != maps_.end()) {
// we would reuse already loaded map. if they were not explicitly added as
// shared maps we would make them such implicitly
VLOG(2) << "map w/ a name: " << map_iter->first
<< " found. fd: " << map_iter->second << " Making it shared";
if (updateSharedMap(map_name, map_iter->second)) {
LOG(ERROR) << "Error while trying to update shared maps";
return closeBpfObject(obj);
}
if (::bpf_map__reuse_fd(map, map_iter->second)) {
LOG(ERROR)
<< "error while trying to reuse fd of a map while reloading bpf program: "
<< map_iter->first;
return closeBpfObject(obj);
}
continue;
}

auto inner_map_iter = innerMapsProto_.find(map_name);
if (inner_map_iter != innerMapsProto_.end()) {
VLOG(2) << "setting inner id for map-in-map: " << inner_map_iter->first
<< " fd: " << inner_map_iter->second;
if (bpf_map__set_inner_map_fd(map, inner_map_iter->second)) {
LOG(ERROR) << "error while trying to set inner map fd for: "
<< inner_map_iter->first
<< " fd: " << inner_map_iter->second;
return closeBpfObject(obj);
}
}
}

if (::bpf_object__load(obj)) {
LOG(ERROR) << "error while trying to load bpf object: " << name;
return closeBpfObject(obj);
}

bpf_object__for_each_program(prog, obj) {
// close old bpf program and (as we successfully reloaded it) and override
// fd with a new one
auto prog_name = ::bpf_program__section_name(prog);
VLOG(4) << "closing old bpf program w/ name: " << prog_name;
auto old_fd = progs_[prog_name];
::close(old_fd);
VLOG(4) << "adding bpf program: " << prog_name
<< " with fd: " << ::bpf_program__fd(prog);
progs_[prog_name] = ::bpf_program__fd(prog);
}

bpf_map__for_each(map, obj) {
auto map_name = bpf_map__name(map);
auto map_iter = maps_.find(map_name);
if (map_iter == maps_.end()) {
VLOG(4) << "adding bpf map: " << map_name
<< " with fd: " << ::bpf_map__fd(map);
maps_[map_name] = bpf_map__fd(map);
}
}
bpfObjects_[name] = obj;
return kSuccess;
}

int BpfLoader::loadBpfObject(
::bpf_object* obj,
const std::string& name,
Expand All @@ -160,9 +265,9 @@ int BpfLoader::loadBpfObject(
::bpf_map* map;

bpf_object__for_each_program(prog, obj) {
if (progs_.find(::bpf_program__title(prog, false)) != progs_.end()) {
if (progs_.find(::bpf_program__section_name(prog)) != progs_.end()) {
LOG(ERROR) << "bpf's program name collision: "
<< ::bpf_program__title(prog, false);
<< ::bpf_program__section_name(prog);
return closeBpfObject(obj);
}
auto prog_type = normalizeBpfProgType(prog, type);
Expand Down Expand Up @@ -204,9 +309,9 @@ int BpfLoader::loadBpfObject(
}

bpf_object__for_each_program(prog, obj) {
VLOG(4) << "adding bpf program: " << ::bpf_program__title(prog, false)
VLOG(4) << "adding bpf program: " << ::bpf_program__section_name(prog)
<< " with fd: " << ::bpf_program__fd(prog);
progs_[::bpf_program__title(prog, false)] = ::bpf_program__fd(prog);
progs_[::bpf_program__section_name(prog)] = ::bpf_program__fd(prog);
}

bpf_map__for_each(map, obj) {
Expand Down
21 changes: 21 additions & 0 deletions katran/lib/BpfLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,19 @@ class BpfLoader {
const bpf_prog_type type = BPF_PROG_TYPE_UNSPEC,
bool use_names = false);

/**
* @param string path to bpf object file
* @param bpf_prog_type type of bpf program to load.
* @return int 0 on success
*
* helper function to reload bpf program. for XDP and TC bpf programs we could
* deduce the type from program's name (if they starts with xdp or cls)
* could throw if object file is malformed
*/
int reloadBpfFromFile(
const std::string& path,
const bpf_prog_type type = BPF_PROG_TYPE_UNSPEC);

/**
* @param string name of the map
* @return int negative on failure, map's fd on success
Expand Down Expand Up @@ -111,6 +124,14 @@ class BpfLoader {
const std::string& name,
const bpf_prog_type type = BPF_PROG_TYPE_UNSPEC);

/**
* helper function to reload bpf object
*/
int reloadBpfObject(
::bpf_object* obj,
const std::string& name,
const bpf_prog_type type = BPF_PROG_TYPE_UNSPEC);

/**
* helper function to close bpf object and return error.
*/
Expand Down
52 changes: 45 additions & 7 deletions katran/lib/KatranLb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ void KatranLb::initialSanityChecking() {
maps.push_back("ch_rings");
maps.push_back("reals");
maps.push_back("stats");
maps.push_back("lru_maps_mapping");
maps.push_back("lru_mapping");
maps.push_back("quic_mapping");

res = getKatranProgFd();
Expand Down Expand Up @@ -290,7 +290,7 @@ void KatranLb::initLrus() {
throw std::runtime_error("can't create prototype map for test lru");
}
}
res = bpfAdapter_.setInnerMapPrototype("lru_maps_mapping", lru_proto_fd);
res = bpfAdapter_.setInnerMapPrototype("lru_mapping", lru_proto_fd);
if (res < 0) {
throw std::runtime_error(folly::sformat(
"can't update inner_maps_fds w/ prototype for main lru, error: {}",
Expand All @@ -307,7 +307,7 @@ void KatranLb::attachLrus() {
key = core;
map_fd = lruMapsFd_[core];
res = bpfAdapter_.bpfUpdateMap(
bpfAdapter_.getMapFdByName("lru_maps_mapping"), &key, &map_fd);
bpfAdapter_.getMapFdByName("lru_mapping"), &key, &map_fd);
if (res < 0) {
throw std::runtime_error(folly::sformat(
"can't attach lru to forwarding core, error: {}",
Expand Down Expand Up @@ -426,10 +426,9 @@ void KatranLb::enableRecirculation() {
uint32_t key = kRecirculationIndex;
int balancer_fd = getKatranProgFd();
auto res = bpfAdapter_.bpfUpdateMap(
bpfAdapter_.getMapFdByName("katran_subprograms"), &key, &balancer_fd);
bpfAdapter_.getMapFdByName("subprograms"), &key, &balancer_fd);
if (res < 0) {
throw std::runtime_error(
"can not update katran_subprograms for recirculation");
throw std::runtime_error("can not update subprograms for recirculation");
}
}

Expand Down Expand Up @@ -543,13 +542,52 @@ void KatranLb::loadBpfProgs() {
progsLoaded_ = true;
if (!config_.disableForwarding && features_.introspection) {
startIntrospectionRoutines();
introspectionStarted_ = true;
}

if (!config_.disableForwarding) {
attachLrus();
}
}

bool KatranLb::reloadBalancerProg(
const std::string& path,
folly::Optional<KatranConfig> config) {
int res;
if (config_.disableForwarding) {
return false;
}

res = bpfAdapter_.reloadBpfProg(path);
if (res) {
return false;
}

if (config.has_value()) {
config_ = *config;
}

config_.balancerProgPath = path;

initialSanityChecking();
featureDiscovering();

if (features_.gueEncap) {
setupGueEnvironment();
}

if (features_.inlineDecap) {
enableRecirculation();
}

if (features_.introspection && !introspectionStarted_) {
startIntrospectionRoutines();
introspectionStarted_ = true;
}
progsReloaded_ = true;
return true;
}

void KatranLb::attachBpfProgs() {
if (!progsLoaded_) {
throw std::invalid_argument("failed to attach bpf prog: prog not loaded");
Expand Down Expand Up @@ -581,7 +619,7 @@ void KatranLb::attachBpfProgs() {
}
}

if (config_.enableHc) {
if (config_.enableHc && !progsReloaded_) {
// attaching healthchecking bpf prog.
auto hc_fd = getHealthcheckerProgFd();
res = bpfAdapter_.addTcBpfFilter(
Expand Down
18 changes: 18 additions & 0 deletions katran/lib/KatranLb.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,14 @@ class KatranLb {
*/
void loadBpfProgs();

/**
* @return true on success
*
* helper function to reload balancer program in runtime
* could throw std::invalid_argument if reload fails.
*/
bool reloadBalancerProg(const std::string& path, folly::Optional<KatranConfig> config = folly::none);

/**
* helper function to attach bpf program (e.g. to rootlet array,
* driver or into tc qdisc)
Expand Down Expand Up @@ -823,6 +831,16 @@ class KatranLb {
* userspace library stats
*/
KatranLbStats lbStats_;

/**
* flag which indicates that introspection routines already started
*/
bool introspectionStarted_{false};

/**
* flag which indicates that bpf program was reloaded
*/
bool progsReloaded_{false};
};

} // namespace katran
Loading

0 comments on commit d195c04

Please sign in to comment.