fabric-testbed / InformationModel

FABRIC Information Model library
MIT License
7 stars 1 forks source link

L3vpn extension #148

Closed ibaldin closed 1 year ago

ibaldin commented 1 year ago

This version supports peer_labels field on all NetworkService objects and adds account_id and bgp_key fields to all Label containers. This way a slice can be specified like so:

        n1 = t.add_node(name='n1', site='MASS')
        n1.add_component(name='nic1', model_type=ComponentModelType.SharedNIC_ConnectX_6)
        n2 = t.add_node(name='n2', site='RENC')
        n2.add_component(name='nic1', model_type=ComponentModelType.SharedNIC_ConnectX_6)

        t.add_network_service(name='ns1', nstype=ServiceType.L3VPN,
                              interfaces=[n1.interface_list[0], n2.interface_list[0]],
                              labels=Labels(asn='654342'),
                              peer_labels=Labels(account_id='secretaccount', asn='123456'))

and when making network advertisements you can do this:

        fac3 = self.topo.add_facility(name='RENCI-Cloud', node_id='RENCI-Cloud-id', site='RENC',
                                      nstype=f.ServiceType.L3VPN,
                                      nslabels=f.Labels( asn='123456', ipv4='192.168.1.1'),
                                      nspeer_labels=f.Labels(asn='65442', bgp_key='secretkey', ipv4='192.168.1.2'),
                                      capacities=f.Capacities(mtu=1500))
        fac3_port_link = self.topo.add_link(name='RENCI-DC-link3', node_id='RENCI-DC-link3-id',
                                            ltype=f.LinkType.L2Path,
                                            interfaces=[fac3.interface_list[0],
                                                        facility_port_facing_port])
        self.assertEqual(fac3.network_services['RENCI-Cloud-ns'].peer_labels.bgp_key, 'secretkey')

Note that above the capacities property goes on the interface connected to L3VPN service, while labels and nspeer_labels go as labels and peer_labels properties of the network service.

This is in PyPi as fim-1.4.0rc0 (i'm switching to release candidates as we are close)

ibaldin commented 1 year ago

@zlion Capacities has an mtu field which is I think what you need (?). It simply lets you specify the desired MTU length whatever it may be.

For the second error I could be missing something, the intent is not to load a blob of JSON but to break it up into Label fields. So you can for instance

local = f.Labels(ipv4_subnet="192.168.1.1/24")
peer = f.Labels(ipv4_subnet="192.168.1.2/24", asn="1", bgp_key="")
t.add_network_service(name='ns1', nstype=ServiceType.L3VPN,
                              interfaces=[n1.interface_list[0], n2.interface_list[0]],
                              labels=local,
                              peer_labels=peer)

I don't fully understand the significance of interface1 vs interface2 - I suspect we need a discussion.

zlion commented 1 year ago

The OESS definition is as follows, https://globalnoc.github.io/OESS/api/vrf

connection
        name
        ...
        local_asn
        endpoint
            node
            interface
            jumbo
            ...
            peers
        endpoint
            node
            interface
            jumbo
            ...
            peers

The networkservicesliver implementation looks like

networkSliver
        name
        ...
        peer_labels
        interfaceinfo
           interfaceSliver
              name
              labels
                  asn
                  ...    
              capacities
                  jumbo
                  ..
           interfaceSliver
              name
              labels
                  asn
                  ...
              capacities
                  jumbo
                  ...

I can manage to map most fields of OESS to networksliver, but has problems with the peers. The peer_labels should contain peers from all endpoints and each peers can be found for given endpoint. Besides, interfaceSlivers are saved in interfaceinfo in dict which is not guaranteed to be ordered (depending on python version).

Here is the value I pass to peer_labs.

peer_labs = {
                'interface1':
                {
                    "bfd": 0,
                    "ip_version": "ipv4",
                    "peer_ip": "192.168.1.1/24",
                    "peer_asn": "1",
                    "local_ip": "192.168.1.2/24",
                    "md5_key": ""
                },
                'interface2':
                {
                    "bfd": 0,
                    "ip_version": "ipv4",
                    "peer_ip": "192.168.2.1/24",
                    "peer_asn": "2",
                    "local_ip": "192.168.2.2/24",
                    "md5_key": ""
                }
            }
zlion commented 1 year ago

As for the jumbo, I understand that in Ethernet, Jumbo frames have payloads more than 1500 bytes but not sure other types of links. Also it is not clear what the MTU size to use if the end-to-end connection across different types of links . So AWS just provides a binary flag to indicate jumbo will be used no matter underlying MTU frame size. Please correct if I am wrong.

ibaldin commented 1 year ago

So technically jumbo frame is anything larger than 1500 octets. So we don't use a binary flag, we just have an MTU setting in capacities. You will need in your code to have an if statement - if MTU>1500, set jumbo=True.

Regarding your other question - sounds like those are interfaces in AL2S. I may be able to provide you with some example code on how to create slivers directly. I realize now the code I showed is too high a level for what you need. I'll see if I can add an example to AMHandlers test harness - this is what I have done in the past.

zlion commented 1 year ago

Great. I will change my code to use MTU capability instead.

I appreciate that you can provide example codes for our use cases. Please take it into consideration that there might be multiple peers objects in one sliver because we support multiple providers. Each peers object is associated with one specific interface as show in the layout above.

Thanks