Add "default" dst while no DST attr responsed from nl

Signed-off-by: Li Chun <chun2.li@intel.com>
This commit is contained in:
Li Chun 2023-03-08 12:46:17 +08:00 committed by Alessandro Boch
parent 55c8b9515a
commit acdc658b86
2 changed files with 222 additions and 1 deletions

View File

@ -1068,6 +1068,9 @@ func (h *Handle) RouteListFiltered(family int, filter *Route, filterMask uint64)
continue
case filterMask&RT_FILTER_DST != 0:
if filter.MPLSDst == nil || route.MPLSDst == nil || (*filter.MPLSDst) != (*route.MPLSDst) {
if filter.Dst == nil {
filter.Dst = genZeroIPNet(family)
}
if !ipNetEqual(route.Dst, filter.Dst) {
continue
}
@ -1262,6 +1265,27 @@ func deserializeRoute(m []byte) (Route, error) {
}
}
// Same logic to generate "default" dst with iproute2 implementation
if route.Dst == nil {
var addLen int
var ip net.IP
switch msg.Family {
case FAMILY_V4:
addLen = net.IPv4len
ip = net.IPv4zero
case FAMILY_V6:
addLen = net.IPv6len
ip = net.IPv6zero
}
if addLen != 0 {
route.Dst = &net.IPNet{
IP: ip,
Mask: net.CIDRMask(int(msg.Dst_len), 8*addLen),
}
}
}
if len(encap.Value) != 0 && len(encapType.Value) != 0 {
typ := int(native.Uint16(encapType.Value[0:2]))
var e Encap
@ -1575,3 +1599,24 @@ func (p RouteProtocol) String() string {
return strconv.Itoa(int(p))
}
}
// genZeroIPNet returns 0.0.0.0/0 or ::/0 for IPv4 or IPv6, otherwise nil
func genZeroIPNet(family int) *net.IPNet {
var addLen int
var ip net.IP
switch family {
case FAMILY_V4:
addLen = net.IPv4len
ip = net.IPv4zero
case FAMILY_V6:
addLen = net.IPv6len
ip = net.IPv6zero
}
if addLen != 0 {
return &net.IPNet{
IP: ip,
Mask: net.CIDRMask(0, 8*addLen),
}
}
return nil
}

View File

@ -77,6 +77,80 @@ func TestRouteAddDel(t *testing.T) {
t.Fatal("Route not removed properly")
}
// add default route test
// equiv: default dev lo
_, defaultDst, _ := net.ParseCIDR("0.0.0.0/0")
route = Route{Dst: defaultDst, LinkIndex: link.Attrs().Index}
if err := RouteAdd(&route); err != nil {
t.Fatal(err)
}
routes, err = RouteList(link, FAMILY_V4)
if err != nil {
t.Fatal(err)
}
if len(routes) != 1 {
t.Fatal("Dev default route not listed properly")
}
if err := RouteDel(&routes[0]); err != nil {
t.Fatal(err)
}
routes, err = RouteList(link, FAMILY_V4)
if err != nil {
t.Fatal(err)
}
if len(routes) != 0 {
t.Fatal("Dev default route not removed properly")
}
// equiv: blackhole default
route = Route{Dst: defaultDst, Type: unix.RTN_BLACKHOLE, Family: FAMILY_V4}
if err := RouteAdd(&route); err != nil {
t.Fatal(err)
}
routes, err = RouteList(nil, FAMILY_V4)
if err != nil {
t.Fatal(err)
}
t.Logf("%+v", routes)
if len(routes) != 1 {
t.Fatal("Blackhole default route not listed properly")
}
if err := RouteDel(&routes[0]); err != nil {
t.Fatal(err)
}
routes, err = RouteList(nil, FAMILY_V4)
if err != nil {
t.Fatal(err)
}
if len(routes) != 0 {
t.Fatal("Blackhole default route not removed properly")
}
// equiv: prohibit default
route = Route{Dst: defaultDst, Type: unix.RTN_PROHIBIT}
if err := RouteAdd(&route); err != nil {
t.Fatal(err)
}
routes, err = RouteList(nil, FAMILY_V4)
if err != nil {
t.Fatal(err)
}
if len(routes) != 1 {
t.Fatal("Prohibit default route not listed properly")
}
if err := RouteDel(&routes[0]); err != nil {
t.Fatal(err)
}
routes, err = RouteList(nil, FAMILY_V4)
if err != nil {
t.Fatal(err)
}
if len(routes) != 0 {
t.Fatal("Prohibit default route not removed properly")
}
}
func TestRoute6AddDel(t *testing.T) {
@ -135,7 +209,7 @@ func TestRoute6AddDel(t *testing.T) {
t.Fatal(err)
}
// cleanup route and dummy interface created for the test
// cleanup route
if len(routeToDstIP) == 0 {
t.Fatal("Route not present")
}
@ -149,6 +223,108 @@ func TestRoute6AddDel(t *testing.T) {
if len(routes) != nroutes {
t.Fatal("Route not removed properly")
}
// add a default link route
_, defaultDst, _ := net.ParseCIDR("::/0")
route = Route{LinkIndex: link.Attrs().Index, Dst: defaultDst}
if err := RouteAdd(&route); err != nil {
t.Fatal(err)
}
routes, err = RouteList(link, FAMILY_V6)
if err != nil {
t.Fatal(err)
}
if len(routes) != nroutes+1 {
t.Fatal("Default route not added properly")
}
// add a default link route
for _, route := range routes {
if route.Dst.String() == defaultDst.String() {
if err := RouteDel(&route); err != nil {
t.Fatal(err)
}
}
}
routes, err = RouteList(link, FAMILY_V6)
if err != nil {
t.Fatal(err)
}
if len(routes) != nroutes {
t.Fatal("Default route not removed properly")
}
// add blackhole default link route
routes, err = RouteList(nil, FAMILY_V6)
if err != nil {
t.Fatal(err)
}
nroutes = len(routes)
route = Route{Type: unix.RTN_BLACKHOLE, Dst: defaultDst}
if err := RouteAdd(&route); err != nil {
t.Fatal(err)
}
routes, err = RouteList(nil, FAMILY_V6)
if err != nil {
t.Fatal(err)
}
if len(routes) != nroutes+1 {
t.Fatal("Blackhole default route not added properly")
}
// add blackhole default link route
for _, route := range routes {
if ipNetEqual(route.Dst, defaultDst) {
if err := RouteDel(&route); err != nil {
t.Fatal(err)
}
}
}
routes, err = RouteList(nil, FAMILY_V6)
if err != nil {
t.Fatal(err)
}
if len(routes) != nroutes {
t.Fatal("Blackhole default route not removed properly")
}
// add prohibit default link route
routes, err = RouteList(nil, FAMILY_V6)
if err != nil {
t.Fatal(err)
}
nroutes = len(routes)
route = Route{Type: unix.RTN_BLACKHOLE, Dst: defaultDst}
if err := RouteAdd(&route); err != nil {
t.Fatal(err)
}
routes, err = RouteList(nil, FAMILY_V6)
if err != nil {
t.Fatal(err)
}
if len(routes) != nroutes+1 {
t.Fatal("Prohibit default route not added properly")
}
// add prohibit default link route
for _, route := range routes {
if ipNetEqual(route.Dst, defaultDst) {
if err := RouteDel(&route); err != nil {
t.Fatal(err)
}
}
}
routes, err = RouteList(nil, FAMILY_V6)
if err != nil {
t.Fatal(err)
}
if len(routes) != nroutes {
t.Fatal("Prohibit default route not removed properly")
}
// cleanup dummy interface created for the test
if err := LinkDel(link); err != nil {
t.Fatal(err)
}