Skip to content

Instantly share code, notes, and snippets.

@toravir
Last active June 30, 2024 15:01
Show Gist options
  • Save toravir/7400f3e032089e19bf0804a870d025be to your computer and use it in GitHub Desktop.
Save toravir/7400f3e032089e19bf0804a870d025be to your computer and use it in GitHub Desktop.
VPP Install BGP Type 5 Route
#!/usr/bin/env python2.7
from __future__ import print_function
import os
import fnmatch
import socket
from vpp_papi import VPP, mac_pton
CLIENT_ID = "Vppclient"
#yVPP_JSON_DIR = '/usr/share/vpp/api/core/'
API_TOP_DIR = '/root/Nov14/build-root/install-vpp_debug-native/vpp/share/vpp/api/'
API_FILE_SUFFIX = '*.api.json'
def load_json_api_files(json_dir, suffix=API_FILE_SUFFIX):
jsonfiles = []
for root, dirnames, filenames in os.walk(json_dir):
for filename in fnmatch.filter(filenames, suffix):
jsonfiles.append(os.path.join(json_dir, filename))
if not jsonfiles:
print('Error: no json api files found')
exit(-1)
return jsonfiles
def connect_vpp(jsonfiles):
vpp = VPP(jsonfiles)
r = vpp.connect("CLIENT_ID")
print("VPP api opened with code: %s" % r)
return vpp
gTableIds = 10
def create_vrf(vrfName):
global gTableIds
gTableIds+=1
rc = vpp.api.ip_table_add_del(is_add=1, table={'table_id':gTableIds, 'is_ip6':0, 'name':vrfName})
print("IP Table Add/Del RC:", rc.retval)
return gTableIds
def newLoopback(vrf, inst, ip):
if inst is not None:
rc = vpp.api.create_loopback_instance(is_specified=1, user_instance=inst)
else:
rc = vpp.api.create_loopback_instance()
print("Create Loopback RC:", rc.retval)
ifIdx = rc.sw_if_index
rc = vpp.api.sw_interface_set_table(sw_if_index=ifIdx, is_ipv6=0, vrf_id=vrf)
print("set vrf for interface RC:", rc.retval)
if ip is not None:
rc = vpp.api.sw_interface_add_del_address(
sw_if_index=ifIdx,
is_add=1,
prefix={'address': {'af': 0,
'un': { 'ip4': socket.inet_aton(ip) }
},
'len':32})
print("set IP of ", ip, " on interface RC:", rc.retval)
rc = vpp.api.sw_interface_set_flags(sw_if_index=ifIdx, flags=1)
print("Bring up interface RC:", rc.retval)
return ifIdx
def newVxlanTunnel(vrf, src, dst, vnid):
rc = vpp.api.vxlan_add_del_tunnel(is_add=1, instance=vnid,
src_address=socket.inet_aton(src),
dst_address=socket.inet_aton(dst),
decap_next_index=0xffffffff,
vni=vnid)
tunIfIdx = rc.sw_if_index
rc = vpp.api.sw_interface_set_table(sw_if_index=tunIfIdx, is_ipv6=0, vrf_id=vrf)
print("set if table RC:", rc.retval)
rc = vpp.api.sw_interface_set_flags(sw_if_index=tunIfIdx, flags=1)
print("set if status RC:", rc.retval)
return tunIfIdx
def newBd(inst, mac, loopIf, tunIf):
rc = vpp.api.bridge_domain_add_del(is_add=1, bd_id=inst, forward=1)
print("create bd RC:", rc.retval)
rc = vpp.api.sw_interface_set_l2_bridge(rx_sw_if_index=loopIf, bd_id=inst, enable=1, port_type=1)
print("set BVI bd RC:", rc.retval)
rc = vpp.api.sw_interface_set_l2_bridge(rx_sw_if_index=tunIf, bd_id=inst, enable=1)
print("set l2 bd RC:", rc.retval)
rc = vpp.api.l2fib_add_del(is_add=1, mac=mac_pton(mac), bd_id=inst, sw_if_index=tunIf, static_mac=1)
print("set l2 fib RC:", rc.retval)
def addStaticArp(ip, ifIdx, mac):
rc = vpp.api.ip_neighbor_add_del(is_add=1, neighbor={'sw_if_index':ifIdx,
'ip_address': {'af': 0,
'un': { 'ip4': socket.inet_aton(ip) }
},
'mac_address':mac,
'flags':1})
print("set static arp RC:", rc.retval)
def setupXConnect(loopIf, tunIf, tnVrf, ip):
rc = vpp.api.sw_interface_set_l2_xconnect(rx_sw_if_index=loopIf, tx_sw_if_index=tunIf, enable=1)
print("set if xconnect RC:", rc.retval)
#rc = vpp.api.sw_interface_set_l2_xconnect(rx_sw_if_index=if2, tx_sw_if_index=if1, enable=1)
#print("set if xconnect RC:", rc.retval)
rc = vpp.api.sw_interface_add_del_address(
sw_if_index=loopIf,
is_add=1,
prefix={'address': {'af': 0,
'un': { 'ip4': socket.inet_aton(ip) }
},
'len':32})
print("set IP of ", ip, " on interface RC:", rc.retval)
lstack = []
while (len(lstack) < 16):
lstack.append({})
rc = vpp.api.l3xc_update(l3xc={'sw_if_index':tunIf,
'is_ip6':0,
'n_paths':1,
'paths':[{'sw_if_index':loopIf,
'table_id':0,
'nh' : {'address': {'ip4': socket.inet_aton(ip)},
'obj_id':loopIf,
},
'label_stack':lstack,
}]
})
print("set l3xc RC:", rc.retval)
def create_type5_route (infraVrf, tnVrf, pfx, srcTep, dstTep, mac, vnid):
dummy_addr1 = "127.0.0.123"
dummy_addr2 = "127.0.0.100"
loopbackIfIdx = newLoopback(vrf=tnVrf, inst=vnid, ip=dummy_addr1)
#loop2 = newLoopback(vrf=tnVrf, inst=vnid+1, ip=None)
tunIfIdx = newVxlanTunnel(infraVrf, srcTep, dstTep, vnid)
newBd(vnid, mac, loopbackIfIdx, tunIfIdx)
addStaticArp(dummy_addr2, loopbackIfIdx, mac)
#setupXConnect(loopbackIfIdx, tunIfIdx, tnVrf, dummy_addr1)
lstack = []
while (len(lstack) < 16):
lstack.append({})
rc = vpp.api.ip_route_add_del(is_add=1, route={'table_id':tnVrf,
'prefix':pfx,
'n_paths':1,
'paths': [{'sw_if_index':loopbackIfIdx,
'table_id':tnVrf,
'nh' : {'address': {'ip4': socket.inet_aton(dummy_addr2)},
'obj_id':loopbackIfIdx,
},
'label_stack':lstack,
}]
})
print("set route add RC:", rc.retval)
return
# Python apis need json definitions to interpret messages
vpp = connect_vpp(load_json_api_files(API_TOP_DIR+"core") + load_json_api_files(API_TOP_DIR+"plugins"))
#1. Setup Infra (Underlay)
#infraVrf = create_vrf("infra")
infraVrf = 0
#infra - srcTep
srcTepIf = newLoopback(infraVrf, None, "100.100.100.100")
#2. Setup Tenant (Overlay)
tnVrf = create_vrf("t0:ctx1")
#3. Create Route in tenant
create_type5_route(infraVrf, tnVrf, pfx="10.0.0.0/24",
srcTep="100.100.100.100",
dstTep="200.200.200.200",
mac="aa:bb:cc:dd:ee:ff",
vnid=11223)
#create_tunnel()
exit(vpp.disconnect())
create packet-generator interface pg0
set interface ip table pg0 11
set interface state pg0 up
set int ip address pg0 1.1.20.2/24
set ip arp pg0 1.1.20.20 f0:0d:f0:0d:f0:0d static
create packet-generator interface pg1
set interface ip table pg1 0
set int state pg1 up
set int ip address pg1 3.3.3.1/24
set ip arp pg1 3.3.3.3 a1:b1:c1:d1:e1:f1 static
ip route add 200.200.200.200/32 table 0 via 3.3.3.3 pg1
trace add pg-input 100
packet-generator enable
#Encap
packet-generator new { name x limit 1 node ethernet-input size 64-64 interface pg0 data { IP4: 1.2.3 -> 4.5.6 ICMP: 1.1.20.20 -> 10.0.0.10 ICMP echo_request incrementing 100 } }
#Decap
packet-generator new { name reply limit 1 node ethernet-input size 114-114 interface pg1 data { hex 0x02feadc6de86a1b1c1d1e1f108004500006400000000fd11632fc8c8c8c864646464722312b50050000008000000002bd700dead000000d7aabbccddeeff080045000032000000003f015cad0a00000a010114140800d9db000102030405060708090a0b0c0d0e0f10111213141516171819 } }
DBGvpp# show trace ------------------- Start of thread 0 vpp_main -------------------
Packet 1
00:00:44:103302: pg-input
stream x, 64 bytes, sw_if_index 5
current data 0, length 64, buffer-pool 0, ref-count 1, trace handle 0x0
IP4: 00:01:00:02:00:03 -> 00:04:00:05:00:06
ICMP: 1.1.20.20 -> 10.0.0.10
tos 0x00, ttl 64, length 50, checksum 0x5bad
fragment id 0x0000
ICMP echo_request checksum 0xd9db
00:00:44:103353: ethernet-input
frame: flags 0x1, hw-if-index 5, sw-if-index 5
IP4: 00:01:00:02:00:03 -> 00:04:00:05:00:06
00:00:44:103390: ip4-input
ICMP: 1.1.20.20 -> 10.0.0.10
tos 0x00, ttl 64, length 50, checksum 0x5bad
fragment id 0x0000
ICMP echo_request checksum 0xd9db
00:00:44:103405: ip4-lookup
fib 1 dpo-idx 0 flow hash: 0x00000000
ICMP: 1.1.20.20 -> 10.0.0.10
tos 0x00, ttl 64, length 50, checksum 0x5bad
fragment id 0x0000
ICMP echo_request checksum 0xd9db
00:00:44:103421: ip4-rewrite
tx_sw_if_index 3 dpo-idx 0 : ipv4 via 127.0.0.100 loop11223: mtu:9000 aabbccddeeffdead000000d70800 flow hash: 0x00000000
00000000: aabbccddeeffdead000000d7080045000032000000003f015cad010114140a00
00000020: 000a0800d9db000102030405060708090a0b0c0d0e0f101112131415
00:00:44:103434: loop11223-output
loop11223 l2_hdr_offset_valid l3_hdr_offset_valid
IP4: de:ad:00:00:00:d7 -> aa:bb:cc:dd:ee:ff
ICMP: 1.1.20.20 -> 10.0.0.10
tos 0x00, ttl 63, length 50, checksum 0x5cad
fragment id 0x0000
ICMP echo_request checksum 0xd9db
00:00:44:103485: l2-input
l2-input: sw_if_index 3 dst aa:bb:cc:dd:ee:ff src de:ad:00:00:00:d7
00:00:44:103493: l2-fwd
l2-fwd: sw_if_index 3 dst aa:bb:cc:dd:ee:ff src de:ad:00:00:00:d7 bd_index 1 result [0x300000004, 4] static age-not
00:00:44:103502: l2-output
l2-output: sw_if_index 4 dst aa:bb:cc:dd:ee:ff src de:ad:00:00:00:d7 data 08 00 45 00 00 32 00 00 00 00 3f 01
00:00:44:103511: vxlan4-encap
VXLAN encap to vxlan_tunnel0 vni 11223
00:00:44:103520: ip4-rewrite
tx_sw_if_index 6 dpo-idx 4 : ipv4 via 3.3.3.3 pg1: mtu:9000 a1b1c1d1e1f102fef53f9c3a0800 flow hash: 0x0000000e
00000000: a1b1c1d1e1f102fef53f9c3a08004500006400000000fd11632f64646464c8c8
00000020: c8c8722312b50050000008000000002bd700aabbccddeeffdead0000
00:00:44:103525: pg1-output
pg1 l2_hdr_offset_valid l3_hdr_offset_valid
IP4: 02:fe:f5:3f:9c:3a -> a1:b1:c1:d1:e1:f1
UDP: 100.100.100.100 -> 200.200.200.200
tos 0x00, ttl 253, length 100, checksum 0x632f
fragment id 0x0000
UDP: 29219 -> 4789
length 80, checksum 0x0000
00:00:44:103530: pg1-tx
buffer 0x9ffd4: current data -50, length 114, buffer-pool 0, ref-count 1, trace handle 0x0
l2-hdr-offset 0 l3-hdr-offset 14
IP4: 02:fe:f5:3f:9c:3a -> a1:b1:c1:d1:e1:f1
UDP: 100.100.100.100 -> 200.200.200.200
tos 0x00, ttl 253, length 100, checksum 0x632f
fragment id 0x0000
UDP: 29219 -> 4789
length 80, checksum 0x0000
Packet 2
00:00:44:103302: pg-input
stream reply, 114 bytes, sw_if_index 6
current data 0, length 114, buffer-pool 0, ref-count 1, trace handle 0x1
IP4: a1:b1:c1:d1:e1:f1 -> 02:fe:ad:c6:de:86
UDP: 200.200.200.200 -> 100.100.100.100
tos 0x00, ttl 253, length 100, checksum 0x632f
fragment id 0x0000
UDP: 29219 -> 4789
length 80, checksum 0x0000
00:00:44:103390: ip4-input
UDP: 200.200.200.200 -> 100.100.100.100
tos 0x00, ttl 253, length 100, checksum 0x632f
fragment id 0x0000
UDP: 29219 -> 4789
length 80, checksum 0x0000
00:00:44:103405: ip4-lookup
fib 0 dpo-idx 5 flow hash: 0x00000000
UDP: 200.200.200.200 -> 100.100.100.100
tos 0x00, ttl 253, length 100, checksum 0x632f
fragment id 0x0000
UDP: 29219 -> 4789
length 80, checksum 0x0000
00:00:44:103427: ip4-local
UDP: 200.200.200.200 -> 100.100.100.100
tos 0x00, ttl 253, length 100, checksum 0x632f
fragment id 0x0000
UDP: 29219 -> 4789
length 80, checksum 0x0000
00:00:44:103445: ip4-udp-lookup
UDP: src-port 29219 dst-port 4789
00:00:44:103478: vxlan4-input
VXLAN decap from vxlan_tunnel0 vni 11223 next 1 error 0
00:00:44:103485: l2-input
l2-input: sw_if_index 4 dst de:ad:00:00:00:d7 src aa:bb:cc:dd:ee:ff
00:00:44:103493: l2-fwd
l2-fwd: sw_if_index 4 dst de:ad:00:00:00:d7 src aa:bb:cc:dd:ee:ff bd_index 1 result [0x700000003, 3] static age-not bvi
00:00:44:103507: ip4-input
ICMP: 10.0.0.10 -> 1.1.20.20
tos 0x00, ttl 63, length 50, checksum 0x5cad
fragment id 0x0000
ICMP echo_request checksum 0xd9db
00:00:44:103517: ip4-lookup
fib 1 dpo-idx 2 flow hash: 0x00000000
ICMP: 10.0.0.10 -> 1.1.20.20
tos 0x00, ttl 63, length 50, checksum 0x5cad
fragment id 0x0000
ICMP echo_request checksum 0xd9db
00:00:44:103520: ip4-rewrite
tx_sw_if_index 5 dpo-idx 2 : ipv4 via 1.1.20.20 pg0: mtu:9000 f00df00df00d02fe89bb0a860800 flow hash: 0x00000000
00000000: f00df00df00d02fe89bb0a86080045000032000000003e015dad0a00000a0101
00000020: 14140800d9db000102030405060708090a0b0c0d0e0f101112131415
00:00:44:103528: pg0-output
pg0 l4-cksum-computed l4-cksum-correct l2_hdr_offset_valid l3_hdr_offset_valid
IP4: 02:fe:89:bb:0a:86 -> f0:0d:f0:0d:f0:0d
ICMP: 10.0.0.10 -> 1.1.20.20
tos 0x00, ttl 62, length 50, checksum 0x5dad
fragment id 0x0000
ICMP echo_request checksum 0xd9db
00:00:44:103536: pg0-tx
buffer 0x9ffad: current data 50, length 64, buffer-pool 0, ref-count 1, trace handle 0x1
l4-cksum-computed l4-cksum-correct l2-hdr-offset 50 l3-hdr-offset 14
IP4: 02:fe:89:bb:0a:86 -> f0:0d:f0:0d:f0:0d
ICMP: 10.0.0.10 -> 1.1.20.20
tos 0x00, ttl 62, length 50, checksum 0x5dad
fragment id 0x0000
ICMP echo_request checksum 0xd9db
DBGvpp#
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment