Skip to content

Add support for max_routes config per VRF #52

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 53 additions & 3 deletions go-server-server/go/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -873,6 +873,47 @@ func ConfigVrouterVrfIdGet(w http.ResponseWriter, r *http.Request) {
Vnid: vnid,
},
}
var ipv4MaxRoutesNum int
ipv4MaxRoutesNumStr, ok := kv["ipv4_max_routes_num"]
if (ok) {
ipv4MaxRoutesNum, err = strconv.Atoi(ipv4MaxRoutesNumStr)
if err != nil {
WriteRequestError(w, http.StatusInternalServerError, "Internal service error, Non numeric ipv4_max_routes_num found in db", []string{}, "")
return
}
var ipv4MaxRoutesThreshold int
ipv4MaxRoutesThresholdStr, ok := kv["ipv4_max_routes_threshold"]
if (ok) {
ipv4MaxRoutesThreshold, err = strconv.Atoi(ipv4MaxRoutesThresholdStr)
if err != nil {
WriteRequestError(w, http.StatusInternalServerError, "Internal service error, Non numeric ipv4_max_routes_threshold found in db", []string{}, "")
return
}
}
tmpIpv4MaxRoutes := MaxRoutesModel { ipv4MaxRoutesNum, ipv4MaxRoutesThreshold }
output.Attr.Ipv4MaxRoutes = &tmpIpv4MaxRoutes
}

var ipv6MaxRoutesNum int
ipv6MaxRoutesNumStr, ok := kv["ipv6_max_routes_num"]
if (ok) {
ipv6MaxRoutesNum, err = strconv.Atoi(ipv6MaxRoutesNumStr)
if err != nil {
WriteRequestError(w, http.StatusInternalServerError, "Internal service error, Non numeric ipv6_max_routes_num found in db", []string{}, "")
return
}
var ipv6MaxRoutesThreshold int
ipv6MaxRoutesThresholdStr, ok := kv["ipv6_max_routes_threshold"]
if (ok) {
ipv6MaxRoutesThreshold, err = strconv.Atoi(ipv6MaxRoutesThresholdStr)
if err != nil {
WriteRequestError(w, http.StatusInternalServerError, "Internal service error, Non numeric ipv6_max_routes_threshold found in db", []string{}, "")
return
}
}
tmpIpv6MaxRoutes := MaxRoutesModel { ipv6MaxRoutesNum, ipv6MaxRoutesThreshold }
output.Attr.Ipv6MaxRoutes = &tmpIpv6MaxRoutes
}

WriteRequestResponse(w, output, http.StatusOK)
}
Expand Down Expand Up @@ -929,12 +970,21 @@ func ConfigVrouterVrfIdPost(w http.ResponseWriter, r *http.Request) {

pt := swsscommon.NewTable(db.swss_db, VNET_TB)
defer pt.Delete()

pt.Set(vnet_id_str, map[string]string{
x := map[string]string{
"vxlan_tunnel": "default_vxlan_tunnel",
"vni": strconv.Itoa(attr.Vnid),
"guid": vars["vnet_name"],
}, "SET", "")
}

if (attr.Ipv4MaxRoutes != nil) {
x["ipv4_max_routes_num"] = strconv.Itoa(attr.Ipv4MaxRoutes.Num)
x["ipv4_max_routes_threshold"] = strconv.Itoa(attr.Ipv4MaxRoutes.Threshold)
}
if (attr.Ipv6MaxRoutes != nil) {
x["ipv6_max_routes_num"] = strconv.Itoa(attr.Ipv6MaxRoutes.Num)
x["ipv6_max_routes_threshold"] = strconv.Itoa(attr.Ipv6MaxRoutes.Threshold)
}
pt.Set(vnet_id_str, x, "SET", "")

w.WriteHeader(http.StatusNoContent)
}
Expand Down
26 changes: 23 additions & 3 deletions go-server-server/go/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"net"
"strconv"
"log"
)

type HeartbeatReturnModel struct {
Expand Down Expand Up @@ -116,8 +117,15 @@ type TunnelDecapReturnModel struct {
Attr TunnelDecapModel `json:"attr"`
}

type MaxRoutesModel struct {
Num int `json:"num"`
Threshold int `json:"threshold"`
}

type VnetModel struct {
Vnid int `json:"vnid"`
Ipv4MaxRoutes *MaxRoutesModel `json:"ipv4_max_routes,omitempty"`
Ipv6MaxRoutes *MaxRoutesModel `json:"ipv6_max_routes,omitempty"`
}

type VnetReturnModel struct {
Expand Down Expand Up @@ -309,14 +317,17 @@ func (m *TunnelDecapModel) UnmarshalJSON(data []byte) (err error) {
func (m *VnetModel) UnmarshalJSON(data []byte) (err error) {
required := struct {
Vnid *int `json:"vnid"`
Ipv4MaxRoutes **MaxRoutesModel `json:"ipv4_max_routes,omitempty"`
Ipv6MaxRoutes **MaxRoutesModel `json:"ipv6_max_routes,omitempty"`
}{}

err = json.Unmarshal(data, &required)

if err != nil {
return
}

log.Printf(
"debug: UnmarshalJSON: VnetModel: %v",
required,
)
if required.Vnid == nil {
err = &MissingValueError{"vnid"}
return
Expand All @@ -328,6 +339,15 @@ func (m *VnetModel) UnmarshalJSON(data []byte) (err error) {
}

m.Vnid = *required.Vnid
if required.Ipv4MaxRoutes != nil {
tmp := MaxRoutesModel {(*(*required.Ipv4MaxRoutes)).Num, (*required.Ipv4MaxRoutes).Threshold}
m.Ipv4MaxRoutes = &tmp
}

if required.Ipv6MaxRoutes != nil {
tmp := MaxRoutesModel {(*(*required.Ipv6MaxRoutes)).Num, (*required.Ipv6MaxRoutes).Threshold}
m.Ipv6MaxRoutes = &tmp
}

return
}
Expand Down
13 changes: 13 additions & 0 deletions sonic_api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1333,6 +1333,15 @@ definitions:
ip_addr:
type: string
description: tunnel local termination IP address
MaxRoutesEntry:
type: object
properties:
num:
description: maximum routes which can advertised
type: integer
threshold:
description: after what threshold should a warning be generated (1-100)
type: integer
VnetEntry:
type: object
required:
Expand All @@ -1342,6 +1351,10 @@ definitions:
type: integer
format: int32
description: vnid
ipv4_max_routes:
$ref: '#/definitions/MaxRoutesEntry'
ipv6_max_routes:
$ref: '#/definitions/MaxRoutesEntry'
VlanEntry:
type: object
properties:
Expand Down
59 changes: 58 additions & 1 deletion test/apitest.py
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,64 @@ def test_vnet_name_mapping_logic(self):
b'vni': b'100'+str(i+6),
b'guid': b'vnet-guid-'+str(i+6)
})


def test_post_vrouter_with_max_routes(self):
self.post_generic_vxlan_tunnel()
r = self.post_config_vrouter_vrf_id("vnet-guid-1", {
'vnid': 1001,
'ipv4_max_routes': {
'num': 1000,
'threshold': 80,
},
'ipv6_max_routes': {
'num': 2000,
'threshold': 80,
},
})
self.assertEqual(r.status_code, 204)

vrouter_table = self.configdb.hgetall(VNET_TB + '|' + VNET_NAME_PREF + '1')
self.assertEqual(vrouter_table, {
b'vxlan_tunnel': b'default_vxlan_tunnel',
b'vni': b'1001',
b'ipv4_max_routes_num': b'1000',
b'ipv4_max_routes_threshold': b'80',
b'ipv6_max_routes_num': b'2000',
b'ipv6_max_routes_threshold': b'80',
b'guid': b'vnet-guid-1'
})

def test_get_vrouter_with_max_routes(self):
self.post_generic_vxlan_tunnel()
r = self.post_config_vrouter_vrf_id("vnet-guid-1", {
'vnid': 1001,
'ipv4_max_routes': {
'num': 1000,
'threshold': 80,
},
'ipv6_max_routes': {
'num': 2000,
'threshold': 80,
},
})
self.assertEqual(r.status_code, 204)
r = self.get_config_vrouter_vrf_id("vnet-guid-1")
self.assertEqual(r.status_code, 200)
j = json.loads(r.text)
self.assertEqual(j, {
'vnet_id': "vnet-guid-1",
'attr': {
'vnid': 1001,
'ipv4_max_routes': {
'num': 1000,
'threshold': 80,
},
'ipv6_max_routes': {
'num': 2000,
'threshold': 80,
},
}
})

# Vlan
def test_vlan_wo_ippref_vnetid_all_verbs(self):
Expand Down