Skip to content

Commit

Permalink
Add to local route DB if ifname present in route add API (#51)
Browse files Browse the repository at this point in the history
* if ifname present then add to local route table

* Check for ifname in every route add

* Check LOCAL_ROUTE_TB wherever ROUTE_TUN_TB is chkd
  • Loading branch information
sumukhatv authored Oct 16, 2020
1 parent 2b4b6d7 commit 37a7c61
Show file tree
Hide file tree
Showing 5 changed files with 230 additions and 85 deletions.
130 changes: 83 additions & 47 deletions go-server-server/go/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -969,12 +969,16 @@ func ConfigVrouterVrfIdRoutesDelete(w http.ResponseWriter, r *http.Request) {
}

var failed []RouteModel
pt := swsscommon.NewProducerStateTable(db.swss_db, ROUTE_TUN_TB)
defer pt.Delete()
pt1 := swsscommon.NewProducerStateTable(db.swss_db, ROUTE_TUN_TB)
defer pt1.Delete()
pt2 := swsscommon.NewProducerStateTable(db.swss_db, LOCAL_ROUTE_TB)
defer pt2.Delete()

for _, r := range routes {
table := generateDBTableKey(db.separator, vnet_id_str, r.IPPrefix)
pt.Del(table, "DEL", "")
table1 := generateDBTableKey(db.separator, vnet_id_str, r.IPPrefix)
pt1.Del(table1, "DEL", "")
table2 := generateDBTableKey(db.separator, vnet_id_str, r.IPPrefix)
pt2.Del(table2, "DEL", "")
}

if len(failed) > 0 {
Expand Down Expand Up @@ -1051,62 +1055,94 @@ func ConfigVrouterVrfIdRoutesPatch(w http.ResponseWriter, r *http.Request) {
return
}

pt := swsscommon.NewProducerStateTable(db.swss_db, ROUTE_TUN_TB)
var pt swsscommon.ProducerStateTable
var rt_tb_name string
defer pt.Delete()

var failed []RouteModel

tunnel_pt := swsscommon.NewProducerStateTable(db.swss_db, ROUTE_TUN_TB)
defer tunnel_pt.Delete()
local_pt := swsscommon.NewProducerStateTable(db.swss_db, LOCAL_ROUTE_TB)
defer local_pt.Delete()

for _, r := range attr {
if r.IfName == "" {
pt = tunnel_pt
rt_tb_name = ROUTE_TUN_TB
if *RunApiAsLocalTestDocker {
rt_tb_name = "_"+ROUTE_TUN_TB
}
} else {
pt = local_pt
rt_tb_name = LOCAL_ROUTE_TB
if *RunApiAsLocalTestDocker {
rt_tb_name = "_"+LOCAL_ROUTE_TB
}
}

bm_next_hop := isLocalTunnelNexthop(r.NextHop)
if bm_next_hop {
log.Printf("Skipping route %v as it is a /32 local subnet route", r)
continue
}

rt_tb_name := ROUTE_TUN_TB
if *RunApiAsLocalTestDocker {
rt_tb_name = "_"+ROUTE_TUN_TB
}
rt_tb_key = generateDBTableKey(db.separator, rt_tb_name, vnet_id_str, r.IPPrefix)

cur_route, err := GetKVs(db.db_num, rt_tb_key)/* generateDBTableKey(db.separator, ROUTE_TUN_TB, vnet_id_str, r.IPPrefix))*/
if err != nil {
r.Error_code = http.StatusInternalServerError
r.Error_msg = "Internal service error"
failed = append(failed, r)
}
if r.Cmd == "delete" {
if cur_route == nil {
r.Error_code = http.StatusNotFound
r.Error_msg = "Not found"
failed = append(failed, r)
} else {
pt.Del(generateDBTableKey(db.separator,vnet_id_str, r.IPPrefix), "DEL", "")
}
} else {
if cur_route != nil {
if cur_route["endpoint"] != r.NextHop ||
cur_route["mac_address"] != r.MACAddress ||
cur_route["vni"] != strconv.Itoa(r.Vnid) {
/* Delete and re-add the route as it is not identical */
pt.Del(generateDBTableKey(db.separator,vnet_id_str, r.IPPrefix), "DEL", "")
} else {
/* Identical route */
continue
}
}
route_map := make(map[string]string)
route_map["endpoint"] = r.NextHop
if(r.MACAddress != "") {
route_map["mac_address"] = r.MACAddress
}
if(r.Vnid != 0) {
route_map["vni"] = strconv.Itoa(r.Vnid)
}
pt.Set(generateDBTableKey(db.separator,vnet_id_str, r.IPPrefix), route_map, "SET", "")

}
}
cur_route, err := GetKVs(db.db_num, rt_tb_key)/* generateDBTableKey(db.separator, ROUTE_TUN_TB, vnet_id_str, r.IPPrefix))*/
if err != nil {
r.Error_code = http.StatusInternalServerError
r.Error_msg = "Internal service error"
failed = append(failed, r)
}
if r.Cmd == "delete" {
if cur_route == nil {
r.Error_code = http.StatusNotFound
r.Error_msg = "Not found"
failed = append(failed, r)
} else {
pt.Del(generateDBTableKey(db.separator,vnet_id_str, r.IPPrefix), "DEL", "")
}
} else {
if cur_route != nil {
if r.IfName == "" {
if cur_route["endpoint"] != r.NextHop ||
cur_route["mac_address"] != r.MACAddress ||
cur_route["vni"] != strconv.Itoa(r.Vnid) {
/* Delete and re-add the route as it is not identical */
pt.Del(generateDBTableKey(db.separator,vnet_id_str, r.IPPrefix), "DEL", "")
} else {
/* Identical route */
continue
}
} else {
if cur_route["ifname"] != r.IfName {
/* Delete and re-add the route as it is not identical */
pt.Del(generateDBTableKey(db.separator,vnet_id_str, r.IPPrefix), "DEL", "")
} else {
/* Identical route */
continue
}
}
}
route_map := make(map[string]string)
if r.IfName == "" {
route_map["endpoint"] = r.NextHop
if(r.MACAddress != "") {
route_map["mac_address"] = r.MACAddress
}
if(r.Vnid != 0) {
route_map["vni"] = strconv.Itoa(r.Vnid)
}
} else {
route_map["ifname"] = r.IfName
if r.NextHop != "" {
route_map["nexthop"] = r.NextHop
}
}
pt.Set(generateDBTableKey(db.separator,vnet_id_str, r.IPPrefix), route_map, "SET", "")
}
}

if len(failed) > 0 {
output := RouteReturnModel {
Expand Down
23 changes: 16 additions & 7 deletions go-server-server/go/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type ConfigResetStatusModel struct {
type RouteModel struct {
Cmd string `json:"cmd,omitempty"`
IPPrefix string `json:"ip_prefix"`
IfName string `json:"ifname,omitempty"`
NextHopType string `json:"nexthop_type,omitempty"`
NextHop string `json:"nexthop"`
MACAddress string `json:"mac_address,omitempty"`
Expand Down Expand Up @@ -171,6 +172,7 @@ func (m *RouteModel) UnmarshalJSON(data []byte) (err error) {
required := struct {
Cmd *string `json:"cmd"`
IPPrefix *string `json:"ip_prefix"`
IfName *string `json:"ifname"`
NextHopType *string `json:"nexthop_type"`
NextHop *string `json:"nexthop"`
MACAddress *string `json:"mac_address"`
Expand All @@ -183,17 +185,19 @@ func (m *RouteModel) UnmarshalJSON(data []byte) (err error) {
if err != nil {
return
}

if required.Cmd == nil {
err = &MissingValueError{"cmd"}
return
} else if required.IPPrefix == nil {
err = &MissingValueError{"ip_prefix"}
return
} else if required.NextHop == nil {
err = &MissingValueError{"nexthop"}
return
}
} else if required.IfName == nil {
if required.NextHop == nil {
err = &MissingValueError{"nexthop"}
return
}
}

if *required.Cmd != "add" && *required.Cmd != "delete" {
err = &InvalidFormatError{Field: "cmd", Message: "Must be add/delete"}
Expand All @@ -211,7 +215,7 @@ func (m *RouteModel) UnmarshalJSON(data []byte) (err error) {
return
}

if required.MACAddress != nil {
if required.IfName == nil && required.MACAddress != nil {
_, err = net.ParseMAC(*required.MACAddress)

if err != nil {
Expand All @@ -223,8 +227,13 @@ func (m *RouteModel) UnmarshalJSON(data []byte) (err error) {

m.Cmd = *required.Cmd
m.IPPrefix = *required.IPPrefix
m.NextHop = *required.NextHop
if required.NextHop != nil {
m.NextHop = *required.NextHop
}
m.Vnid = required.Vnid
if required.IfName != nil {
m.IfName = *required.IfName
}
return
}

Expand Down
31 changes: 28 additions & 3 deletions go-server-server/go/persistent.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,12 +261,23 @@ func SwssGetVrouterRoutes(vnet_id_str string, vnidMatch int, ipFilter string) (r
pattern = generateDBTableKey(db.separator, rt_tb_name, vnet_id_str, ipFilter)
routes = []RouteModel{}

kv, err := GetKVsMulti(db.db_num,pattern)
if err != nil {
kv1, err1 := GetKVsMulti(db.db_num,pattern)
if err1 != nil {
return
}

for k, kvp := range kv {
rt_tb_name = LOCAL_ROUTE_TB
if *RunApiAsLocalTestDocker {
rt_tb_name = "_"+LOCAL_ROUTE_TB
}
pattern = generateDBTableKey(db.separator, rt_tb_name, vnet_id_str, ipFilter)

kv2, err2 := GetKVsMulti(db.db_num,pattern)
if err2 != nil {
return
}

for k, kvp := range kv1 {
ipprefix := strings.Split(k, db.separator)[2]

routeModel := RouteModel{
Expand All @@ -291,6 +302,20 @@ func SwssGetVrouterRoutes(vnet_id_str string, vnidMatch int, ipFilter string) (r
routes = append(routes, routeModel)
}

for k, kvp := range kv2 {
ipprefix := strings.Split(k, db.separator)[2]

routeModel := RouteModel{
IPPrefix: ipprefix,
NextHop: kvp["nexthop"],
}

if ifname, ok := kvp["ifname"]; ok {
routeModel.IfName = ifname
}

routes = append(routes, routeModel)
}
return
}

Expand Down
3 changes: 3 additions & 0 deletions sonic_api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1311,6 +1311,9 @@ definitions:
mac_address:
type: string
description: mac_address of the target VM
ifname:
type: string
description: Interface name for local route. When ifname is mentioned, nexthop is optional
vnid:
type: integer
format: int32
Expand Down
Loading

0 comments on commit 37a7c61

Please sign in to comment.