Hi Vincent,
Here is a brief write-up about how we can (and some of it we have already
done) make name-space and vrf-device based vrfs co-exist.
In the kernel, hierarchically, vrf-devices are well within a name-space.
We can keep the same in quagga. In fact, its looking quite feasible to
leverage both to take the effective vrf scale further.
I am attaching it as a text-file for a better view of the ansii art.
thanks
Vipin
On Fri, Jan 8, 2016 at 5:21 AM, Vincent JARDIN <[email protected]>
wrote:
> Someone needs to add the freebsd jail's support. The VRF framework allows
> it.
> Le 8 janv. 2016 13:31, "Donald Sharp" <[email protected]> a
> écrit :
>
>> Vincent -
>>
>> Vipin and I are working on breaking the patch up now to get the data
>> structures in place upstream. Hopefully in the next week or so.
>>
>> Sami -
>>
>> The code will just work if there is no kernel vrf support, ie everything
>> will just be in the default vrf. I'm not aware of any work being done in
>> this regards on freebsd, but that doesn't mean anything because I'm not
>> plugged into that community. The process should be the same, though from
>> Quagga's perspective
>>
>> donald
>>
>>
>>
>> On Fri, Jan 8, 2016 at 7:27 AM, Sami Halabi <[email protected]> wrote:
>>
>>> hi,
>>> great work.
>>> is this work supported in freebsd? i noticed you mentioned netlink wixh
>>> is linux soecific.
>>>
>>> Sami
>>> בתאריך 8 בינו׳ 2016 11:04 AM, "Vincent JARDIN" <
>>> [email protected]> כתב:
>>>
>>> It looks good. Which patch serie to check?
>>>> Le 8 janv. 2016 07:09, "Vipin Kumar" <[email protected]> a
>>>> écrit :
>>>>
>>>>> Significant progress has been made on this project. I had sent a few
>>>>> emails to quagga-dev outlining the approach for this project -- to
>>>>> leverage
>>>>> current VRF lib and BGP multi-instance support. We had a fruitful
>>>>> discussion about that and the config model as well.
>>>>>
>>>>> Will be sending the changes(with explanations) to the data-structures
>>>>> like vrf, zebra_vrf and interface soon. And also some of the new
>>>>> trees/lists that were needed to keep vrf (devices) within a name-space,
>>>>> take care of forward-referencing of VRFs, and deal with challenges
>>>>> associated with address notifications via netlink, etc.
>>>>>
>>>>> Created a new data-structure zebra_ns, so that name-space and vrf
>>>>> device models don't just co-exist, but also work in hierarchical way to
>>>>> possibly scale the number of vrfs/instances further.
>>>>>
>>>>> All the configuration/show/clear is by vrf-device name,
>>>>> implementation however internally still uses the vrf-id for efficiency
>>>>> reasons. vrf-device index generated by the kernel is used as the vrf-id.
>>>>>
>>>>> We will also release/submit patches with descriptions in incremental
>>>>> (logical) batches as testing/sanities progress and clears.
>>>>>
>>>>> For now, here are some actual outputs based on the current
>>>>> implementation of this project.
>>>>>
>>>>> *1. Sample Running config*
>>>>>
>>>>> bgp multiple-instance
>>>>> !
>>>>> !
>>>>> interface swp1 vrf boo
>>>>> link-detect
>>>>> !
>>>>> interface swp2 vrf foo
>>>>> link-detect
>>>>> !
>>>>> interface swp3 vrf zoo
>>>>> link-detect
>>>>> !
>>>>> vrf boo
>>>>> !
>>>>> vrf foo
>>>>> !
>>>>> vrf zoo
>>>>> !
>>>>> router bgp 65001 vrf boo
>>>>> neighbor 11.0.0.2 remote-as 65001
>>>>> address-family ipv4 unicast
>>>>> redistribute static
>>>>> neighbor 11.0.0.2 activate
>>>>> exit-address-family
>>>>> !
>>>>> router bgp 65001 vrf foo
>>>>> neighbor 11.0.1.2 remote-as 65001
>>>>> address-family ipv4 unicast
>>>>> redistribute static
>>>>> neighbor 11.0.1.2 activate
>>>>> exit-address-family
>>>>> !
>>>>> router bgp 65001 vrf zoo
>>>>> neighbor 11.0.2.2 remote-as 65001
>>>>> address-family ipv4 unicast
>>>>> redistribute static
>>>>> neighbor 11.0.2.2 activate
>>>>> exit-address-family
>>>>> !
>>>>> ip route 10.10.10.10/32 Null0 vrf boo
>>>>> ip route 11.11.11.11/32 Null0 vrf foo
>>>>> ip route 12.12.12.12/32 Null0 vrf zoo
>>>>> !
>>>>>
>>>>>
>>>>>
>>>>> *2. New config modes*
>>>>>
>>>>> * Global VRF*
>>>>>
>>>>> r1(config)#?
>>>>> ..
>>>>> vrf Select a VRF to configure
>>>>> ..
>>>>> r1(config)# vrf
>>>>> NAME VRF's name
>>>>> r1(config)# vrf foo
>>>>> <cr>
>>>>> r1(config)# vrf foo
>>>>> r1(config-vrf)#
>>>>>
>>>>> Note: This mode works just the way it is for interfaces, i.e. quagga
>>>>> can hold the config and (in future) commands within it, VRF becomes active
>>>>> (usable by protocols BGP, static, ..) only after its been created in
>>>>> kernel
>>>>> and learnt by quagga via netlink interface.
>>>>>
>>>>>
>>>>> * Interface VRF*
>>>>>
>>>>>
>>>>> r1(config)# interface swp2
>>>>> <cr>
>>>>> vrf Specify the VRF
>>>>> r1(config)# interface swp2 vrf
>>>>> NAME The VRF name
>>>>> r1(config)# interface swp2 vrf foo
>>>>> <cr>
>>>>> r1(config)# interface swp2 vrf foo
>>>>> r1(config-if)#
>>>>>
>>>>>
>>>>> * BGP VRF*
>>>>>
>>>>> r1(config)# router bgp 65001
>>>>> <cr>
>>>>> view BGP view
>>>>> vrf BGP VRF
>>>>> r1(config)# router bgp 65001 vrf
>>>>> WORD View/VRF name
>>>>> r1(config)# router bgp 65001 vrf foo
>>>>> r1(config-router)#
>>>>>
>>>>>
>>>>> Note: BGP VRF instances (struct bgp) have some state of
>>>>> their own now.Which comes handy as and when VRF creation/deletion
>>>>> is learnt by BGP via zebra api.
>>>>> bgp_create() -> bgp_instance_up() ->
>>>>> bgp_instance_down() ->bgp_delete ()
>>>>>
>>>>> When BGP instance is configured as view, it will
>>>>> act in view mode just like it used to.
>>>>> Introduced instance type - view or vrf, so
>>>>> implementation can differentiate as needed.
>>>>>
>>>>> *3. Sample (of a few) show commands*
>>>>>
>>>>> *r1# show vrf*
>>>>> vrf boo id 7 table 10
>>>>> vrf foo id 8 table 11
>>>>> vrf zoo id 9 table 12
>>>>> r1#
>>>>>
>>>>> *r1# show interface vrf foo*
>>>>> Interface swp2 is up, line protocol is up
>>>>> PTM status: disabled
>>>>> vrf: 8
>>>>> Description: r3
>>>>> index 4 metric 0 mtu 1500
>>>>> flags: <UP,BROADCAST,RUNNING,MULTICAST>
>>>>> HWaddr: 00:02:00:00:00:0a
>>>>> inet 11.0.1.1/24
>>>>> inet6 fe80::202:ff:fe00:a/64
>>>>> ND advertised reachable time is 0 milliseconds
>>>>> ND advertised retransmit interval is 0 milliseconds
>>>>> ND router advertisements are sent every 600 seconds
>>>>> ND router advertisements lifetime tracks ra-interval
>>>>> ND router advertisement default router preference is medium
>>>>> Hosts use stateless autoconfig for addresses.
>>>>>
>>>>>
>>>>> *r1# show ip bgp vrf foo summary*
>>>>> BGP router identifier 11.0.1.1, local AS number 65001 vrf-id 8
>>>>> BGP table version 5
>>>>> RIB entries 9, using 1080 bytes of memory
>>>>> Peers 1, using 16 KiB of memory
>>>>>
>>>>> Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down
>>>>> State/PfxRcd
>>>>> r3(11.0.1.2) 4 65001 134 135 0 0 0 00:06:37
>>>>> 4
>>>>>
>>>>> Total number of neighbors 1
>>>>> r1#
>>>>>
>>>>> *r1# show ip bgp vrf foo*
>>>>> BGP table version is 5, local router ID is 11.0.1.1
>>>>> Status codes: s suppressed, d damped, h history, * valid, > best, =
>>>>> multipath,
>>>>> i internal, r RIB-failure, S Stale, R Removed
>>>>> Origin codes: i - IGP, e - EGP, ? - incomplete
>>>>>
>>>>> Network Next Hop Metric LocPrf Weight Path
>>>>> *>i11.0.1.0/24 11.0.1.2 0 100 0 i
>>>>> *>i11.0.5.0/24 11.0.1.2 0 100 0 i
>>>>> *>i11.0.7.0/24 11.0.1.2 0 100 0 i
>>>>> *>i11.0.8.0/24 11.0.1.2 0 100 0 i
>>>>> *> 11.11.11.11/32 0.0.0.0 0 32768 ?
>>>>>
>>>>> Total number of prefixes 5
>>>>>
>>>>> *r1# show ip nht vrf boo*
>>>>> 11.0.0.2
>>>>> resolved via connected
>>>>> is directly connected, unknown
>>>>> Client list: bgp(fd 16)
>>>>> *r1# show ip nht vrf foo*
>>>>> 11.0.1.2
>>>>> resolved via connected
>>>>> is directly connected, unknown
>>>>> Client list: bgp(fd 16)
>>>>> *r1# show ip nht vrf zoo*
>>>>> 11.0.2.2
>>>>> resolved via connected
>>>>> is directly connected, unknown
>>>>> Client list: bgp(fd 16)
>>>>>
>>>>>
>>>>> *r1# show ip route vrf boo*
>>>>> Codes: K - kernel route, C - connected, S - static, R - RIP,
>>>>> O - OSPF, I - IS-IS, B - BGP, A - Babel, T - Table,
>>>>> > - selected route, * - FIB route
>>>>>
>>>>> S>* 10.10.10.10/32 [1/0] [vrf 7] is directly connected, Null0, bh
>>>>> B 11.0.0.0/24 [200/0] [vrf 7] via 11.0.0.2 inactive, 00:54:49
>>>>> C>* 11.0.0.0/24 [vrf 7] is directly connected, swp1
>>>>> B>* 11.0.4.0/24 [200/0] [vrf 7] via 11.0.0.2, swp1, 00:54:49
>>>>> B>* 11.0.7.0/24 [200/0] [vrf 7] via 11.0.0.2, swp1, 00:54:49
>>>>> B>* 11.0.9.0/24 [200/0] [vrf 7] via 11.0.0.2, swp1, 00:54:49
>>>>>
>>>>> *r1# show ip route vrf foo*
>>>>> Codes: K - kernel route, C - connected, S - static, R - RIP,
>>>>> O - OSPF, I - IS-IS, B - BGP, A - Babel, T - Table,
>>>>> > - selected route, * - FIB route
>>>>>
>>>>> B 11.0.1.0/24 [200/0] [vrf 8] via 11.0.1.2 inactive, 00:07:50
>>>>> C>* 11.0.1.0/24 [vrf 8] is directly connected, swp2
>>>>> B>* 11.0.5.0/24 [200/0] [vrf 8] via 11.0.1.2, swp2, 00:07:50
>>>>> B>* 11.0.7.0/24 [200/0] [vrf 8] via 11.0.1.2, swp2, 00:07:50
>>>>> B>* 11.0.8.0/24 [200/0] [vrf 8] via 11.0.1.2, swp2, 00:07:50
>>>>> S>* 11.11.11.11/32 [1/0] [vrf 8] is directly connected, Null0, bh
>>>>> r1#
>>>>>
>>>>>
>>>>>
>>>>> *4. Steps to create a VRF device*
>>>>>
>>>>> ip link add dev boo type vrf table 10
>>>>> ip link set dev boo up
>>>>>
>>>>> *5. Steps to enslave an interface to a VRF device *
>>>>>
>>>>>
>>>>> ip link set dev swp1 master boo
>>>>>
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> Quagga-dev mailing list
>>>>> [email protected]
>>>>> https://lists.quagga.net/mailman/listinfo/quagga-dev
>>>>>
>>>>
>>>> _______________________________________________
>>>> Quagga-dev mailing list
>>>> [email protected]
>>>> https://lists.quagga.net/mailman/listinfo/quagga-dev
>>>>
>>>
>>
How it is with 6wind vrf lib patch —
Configuration:
vrf <vrf-id> ns-name <path>
Main data-structures:
Global vrf_table which holds vrfs in a tree indexed by vrf-id.
Interface list is moved inside VRFs.
vrf_init() creates a default vrf.
+----------------------+
| struct vrf { |
| |
| vrf_id_t vrf_id;|
| char *name; |
| |
| void *info; +---------+
| } | |
+----------------------+ |
| (in case of zebra)
+---+----------------+
| struct zebra_vrf { |
| /*tables etc. *|
| |
| } |
+--------------------+
Here is how name-space based model is filling well after integration with
vrf-devices
Configuration:
name-space <ns-id> ns-name <path> // proposing renaming of the previous vrf
command.
vrf <name> // the new config mode
As for the reflection of hierarchies in the running config, we have two
possibilities:
1. Continue with the approach we took with interface and vrf, where a vrf
is shown in the interface command. Do the same with the vrf command and show
name-space next to the vrfs it owns.
name-space ID name NSNAME
vrf VRFNAME name-space NSNAME
interface IFNAME vrf VRFNAME
2. Implement name-space config mode which contains VRFs and interfaces
within it.
We believe (1) is sufficient.
Main data-structures:
Global ns_table which holds NSs in a tree indexed by ns-id.
vrf_table is moved inside name-space structure.
ns/vrf_init() create default ns/vrf.
+-------------------------+
|struct zebra_ns { |
| ns_id_t nsid; |
| |
| /* vrf_table etc. */ |
| +----+
|} | | +--------------+
+-------------------------+ +——>+struct vrf { |
| | | +--------------------+
| |} +> |struct zebra_vrf { |
| +--------------+ | |
| |} |
| | |
| +--------------------+
|
+-->
|
|
+
* Not sure at this point if moving name-space structure also in the library
makes sense of it can be kept zebra specific zebra_ns to keep things simple.
Config scenarios:
1. name-spaces (only) to realize vrfs — in this case nodes (zebra_ns) within
the ns_table will grow, where each zebra_ns has a default vrf in it.
2. vrf-devices (only) to realize vrfs — in this case nodes (struct vrf)
within the vrf_table in the default zebra_ns will grow.
3. name-spaces and vrf-devices within them — in this case both ns_table as
well as the vrf_table within them grow
_______________________________________________
Quagga-dev mailing list
[email protected]
https://lists.quagga.net/mailman/listinfo/quagga-dev