From 1eb1808e32eedc2c116757cb72c9e2efc0cd0a22 Mon Sep 17 00:00:00 2001 From: Ravi Vasanthm Date: Fri, 3 Jan 2020 16:08:02 -0800 Subject: [PATCH 1/7] DHCP support for Management interface. --- .../openconfig-interfaces-annot.yang | 26 ++ .../extensions/openconfig-interfaces-ext.yang | 37 +- models/yang/sonic/sonic-mgmt-interface.yang | 18 + src/translib/transformer/xfmr_intf.go | 358 +++++++++++++----- 4 files changed, 339 insertions(+), 100 deletions(-) diff --git a/models/yang/annotations/openconfig-interfaces-annot.yang b/models/yang/annotations/openconfig-interfaces-annot.yang index c7c71e2e83..aa96403abe 100644 --- a/models/yang/annotations/openconfig-interfaces-annot.yang +++ b/models/yang/annotations/openconfig-interfaces-annot.yang @@ -150,6 +150,32 @@ module openconfig-interfaces-annot { } } + deviation /oc-intf:interfaces/oc-intf:interface/oc-intf:subinterfaces/oc-intf:subinterface/oc-ip:ipv4/oc-ip:config { + deviate add { + sonic-ext:table-name "NONE"; + sonic-ext:subtree-transformer "intf_ip_addr_xfmr"; + } + } + deviation /oc-intf:interfaces/oc-intf:interface/oc-intf:subinterfaces/oc-intf:subinterface/oc-ip:ipv4/oc-ip:state { + deviate add { + sonic-ext:table-name "NONE"; + sonic-ext:subtree-transformer "intf_ip_addr_xfmr"; + } + } + + deviation /oc-intf:interfaces/oc-intf:interface/oc-intf:subinterfaces/oc-intf:subinterface/oc-ip:ipv6/oc-ip:config { + deviate add { + sonic-ext:table-name "NONE"; + sonic-ext:subtree-transformer "intf_ip_addr_xfmr"; + } + } + deviation /oc-intf:interfaces/oc-intf:interface/oc-intf:subinterfaces/oc-intf:subinterface/oc-ip:ipv6/oc-ip:state { + deviate add { + sonic-ext:table-name "NONE"; + sonic-ext:subtree-transformer "intf_ip_addr_xfmr"; + } + } + deviation /oc-intf:interfaces/oc-intf:interface/oc-intf:state/oc-intf:counters { deviate add { sonic-ext:subtree-transformer "intf_get_counters_xfmr"; diff --git a/models/yang/extensions/openconfig-interfaces-ext.yang b/models/yang/extensions/openconfig-interfaces-ext.yang index af161e48ca..d64a9770f8 100755 --- a/models/yang/extensions/openconfig-interfaces-ext.yang +++ b/models/yang/extensions/openconfig-interfaces-ext.yang @@ -38,6 +38,31 @@ module openconfig-interfaces-ext { } } + augment "/oc-intf:interfaces/oc-intf:interface/oc-intf:subinterfaces/oc-intf:subinterface/oc-ip:ipv4/oc-ip:config" { + leaf default-gwaddr { + type oc-inet:ipv4-address; + description "IPv4 Default Gateway address"; + } + } + augment "/oc-intf:interfaces/oc-intf:interface/oc-intf:subinterfaces/oc-intf:subinterface/oc-ip:ipv4/oc-ip:state" { + leaf default-gwaddr { + type oc-inet:ipv4-address; + description "IPv4 Default Gateway address"; + } + } + augment "/oc-intf:interfaces/oc-intf:interface/oc-intf:subinterfaces/oc-intf:subinterface/oc-ip:ipv6/oc-ip:config" { + leaf default-gwaddr { + type oc-inet:ipv6-address; + description "IPv6 Default Gateway address"; + } + } + augment "/oc-intf:interfaces/oc-intf:interface/oc-intf:subinterfaces/oc-intf:subinterface/oc-ip:ipv6/oc-ip:state" { + leaf default-gwaddr { + type oc-inet:ipv6-address; + description "IPv6 Default Gateway address"; + } + } + augment "/oc-intf:interfaces/oc-intf:interface/oc-intf:subinterfaces/oc-intf:subinterface/oc-ip:ipv4/oc-ip:addresses/oc-ip:address/oc-ip:config" { leaf gw-addr { type oc-inet:ipv4-address; @@ -111,12 +136,6 @@ module openconfig-interfaces-ext { deviation /oc-intf:interfaces/oc-intf:interface/oc-intf:subinterfaces/oc-intf:subinterface/oc-ip:ipv4/oc-ip:unnumbered { deviate not-supported; } - deviation /oc-intf:interfaces/oc-intf:interface/oc-intf:subinterfaces/oc-intf:subinterface/oc-ip:ipv4/oc-ip:config { - deviate not-supported; - } - deviation /oc-intf:interfaces/oc-intf:interface/oc-intf:subinterfaces/oc-intf:subinterface/oc-ip:ipv4/oc-ip:state { - deviate not-supported; - } deviation /oc-intf:interfaces/oc-intf:interface/oc-intf:subinterfaces/oc-intf:subinterface/oc-ip:ipv6/oc-ip:addresses/oc-ip:address/oc-ip:vrrp { deviate not-supported; @@ -127,12 +146,6 @@ module openconfig-interfaces-ext { deviation /oc-intf:interfaces/oc-intf:interface/oc-intf:subinterfaces/oc-intf:subinterface/oc-ip:ipv6/oc-ip:unnumbered { deviate not-supported; } - deviation /oc-intf:interfaces/oc-intf:interface/oc-intf:subinterfaces/oc-intf:subinterface/oc-ip:ipv6/oc-ip:config { - deviate not-supported; - } - deviation /oc-intf:interfaces/oc-intf:interface/oc-intf:subinterfaces/oc-intf:subinterface/oc-ip:ipv6/oc-ip:state { - deviate not-supported; - } deviation /oc-intf:interfaces/oc-intf:interface/oc-intf:subinterfaces/oc-intf:subinterface/oc-ip:ipv6/oc-ip-ext:autoconf { deviate not-supported; } diff --git a/models/yang/sonic/sonic-mgmt-interface.yang b/models/yang/sonic/sonic-mgmt-interface.yang index 80f3cbc576..f095aa1c79 100644 --- a/models/yang/sonic/sonic-mgmt-interface.yang +++ b/models/yang/sonic/sonic-mgmt-interface.yang @@ -45,6 +45,24 @@ module sonic-mgmt-interface { } } + leaf ipv4_default_gwaddr { + type inet:ipv4-address; + } + + leaf ipv6_default_gwaddr { + type inet:ipv6-address; + } + + leaf ipv4_dhcp_client { + type boolean; + default false; + } + + leaf ipv6_dhcp_client { + type boolean; + default false; + } + leaf vrf-name { type leafref { path "/mvrf:sonic-mgmt-vrf/mvrf:MGMT_VRF_CONFIG/mvrf:MGMT_VRF_CONFIG_LIST/mvrf:vrf_global_name"; diff --git a/src/translib/transformer/xfmr_intf.go b/src/translib/transformer/xfmr_intf.go index 28048badff..4446d16f53 100644 --- a/src/translib/transformer/xfmr_intf.go +++ b/src/translib/transformer/xfmr_intf.go @@ -447,12 +447,20 @@ var intf_table_xfmr TableXfmrFunc = func (inParams XfmrParams) ([]string, error) } else if strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/ipv4/addresses/address/config") || strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/openconfig-if-ip:ipv4/addresses/address/config") || strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/openconfig-if-ip:ipv6/addresses/address/config") || - strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/ipv6/addresses/address/config") { + strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/ipv6/addresses/address/config") || + strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/ipv4/config") || + strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/openconfig-if-ip:ipv4/config") || + strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/ipv6/config") || + strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/openconfig-if-ip:ipv6/config") { tblList = append(tblList, intTbl.cfgDb.intfTN) } else if strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/ipv4/addresses/address/state") || strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/openconfig-if-ip:ipv4/addresses/address/state") || strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/openconfig-if-ip:ipv6/addresses/address/state") || - strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/ipv6/addresses/address/state") { + strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/ipv6/addresses/address/state") || + strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/ipv4/state") || + strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/openconfig-if-ip:ipv4/state") || + strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/ipv6/state") || + strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/openconfig-if-ip:ipv6/state") { tblList = append(tblList, intTbl.appDb.intfTN) } else if strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/ipv4/addresses") || strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/openconfig-if-ip:ipv4/addresses") || @@ -758,6 +766,36 @@ func intf_ip_addr_del (d *db.DB , ifName string, tblName string, subIntf *ocbind subIntfmap := make(map[string]map[string]db.Value) intfIpMap := make(map[string]db.Value) + intfType, _, _ := getIntfTypeByName(ifName) + + if intfType == IntfTypeMgmt { + if ((subIntf.Ipv4 != nil && subIntf.Ipv4.Config != nil) || (subIntf.Ipv6 != nil && subIntf.Ipv6.Config != nil)) { + if _, ok := subIntfmap[tblName]; !ok { + subIntfmap[tblName] = make (map[string]db.Value) + } + ifdb := make(map[string]string) + value := db.Value{Field: ifdb} + + if subIntf.Ipv4 != nil && subIntf.Ipv4.Config != nil { + if subIntf.Ipv4.Config.DefaultGwaddr != nil { + value.Set("ipv4_default_gwaddr", "") + } + if subIntf.Ipv4.Config.DhcpClient != nil { + value.Set("ipv4_dhcp_client", "") + } + } + if subIntf.Ipv6 != nil && subIntf.Ipv6.Config != nil { + if subIntf.Ipv6.Config.DefaultGwaddr != nil { + value.Set("ipv6_default_gwaddr", "") + } + if subIntf.Ipv6.Config.DhcpClient != nil { + value.Set("ipv6_dhcp_client", "") + } + } + subIntfmap[tblName][ifName] = value + } + } + if subIntf.Ipv4 != nil && subIntf.Ipv4.Addresses != nil { if len(subIntf.Ipv4.Addresses.Address) < 1 { ipMap, _:= getIntfIpByName(d, tblName, ifName, true, false, "") @@ -818,7 +856,9 @@ func intf_ip_addr_del (d *db.DB , ifName string, tblName string, subIntf *ocbind IntfMap := IntfMapObj.Field if len(IntfMap) == 1 { if _, ok := IntfMap["NULL"]; ok { - subIntfmap[tblName][ifName] = data + if _, ok := subIntfmap[tblName][ifName]; !ok { + subIntfmap[tblName][ifName] = data + } } } } @@ -937,7 +977,65 @@ var YangToDb_intf_ip_addr_xfmr SubTreeXfmrYangToDb = func(inParams XfmrParams) ( } + if intfType == IntfTypeMgmt && ((subIntfObj.Ipv4 != nil && subIntfObj.Ipv4.Config != nil) || (subIntfObj.Ipv6 != nil && subIntfObj.Ipv6.Config != nil)) { + if _, ok := subIntfmap[tblName][ifName]; !ok { + ifdb := make(map[string]string) + value := db.Value{Field: ifdb} + if _, ok := subIntfmap[tblName]; !ok { + subIntfmap[tblName] = make(map[string]db.Value) + } + subIntfmap[tblName][ifName] = value + } + + value := subIntfmap[tblName][ifName] + if subIntfObj.Ipv4 != nil && subIntfObj.Ipv4.Config != nil { + ipv4Cfg := subIntfObj.Ipv4.Config + if ipv4Cfg.DefaultGwaddr != nil { + value.Set("ipv4_default_gwaddr", *ipv4Cfg.DefaultGwaddr) + } + if ipv4Cfg.DhcpClient != nil { + if *ipv4Cfg.DhcpClient == true { + ipMap, _ := getIntfIpByName(inParams.d, tblName, ifName, true, false, "") + if (ipMap != nil && len(ipMap) > 0) || (subIntfObj.Ipv4.Addresses != nil && len(subIntfObj.Ipv4.Addresses.Address) > 0) { + errStr := "DHCPClient for IPV4 can't be enabled when static IP's are configured." + log.Info("YangToDb_intf_subintf_ip_xfmr : " + errStr + " ", ipMap) + return subIntfmap, errors.New(errStr) + } + value.Set("ipv4_dhcp_client", "true") + } else { + value.Set("ipv4_dhcp_client", "false") + } + } + } + + if subIntfObj.Ipv6 != nil && subIntfObj.Ipv6.Config != nil { + ipv6Cfg := subIntfObj.Ipv6.Config + if ipv6Cfg.DefaultGwaddr != nil { + value.Set("ipv6_default_gwaddr", *ipv6Cfg.DefaultGwaddr) + } + if ipv6Cfg.DhcpClient != nil { + if *ipv6Cfg.DhcpClient == true { + ipMap, _ := getIntfIpByName(inParams.d, tblName, ifName, false, true, "") + if (ipMap != nil && len(ipMap) > 0) || (subIntfObj.Ipv6.Addresses != nil && len(subIntfObj.Ipv6.Addresses.Address) > 0) { + errStr := "DHCPClient for IPV6 can't be enabled when static IP's are configured." + log.Info("YangToDb_intf_subintf_ip_xfmr : " + errStr + " ", ipMap) + return subIntfmap, errors.New(errStr) + } + value.Set("ipv6_dhcp_client", "true") + } else { + value.Set("ipv6_dhcp_client", "false") + } + } + } + subIntfmap[tblName][ifName] = value + } + if subIntfObj.Ipv4 != nil && subIntfObj.Ipv4.Addresses != nil { + if intfType == IntfTypeMgmt && len(subIntfObj.Ipv4.Addresses.Address) > 0 && ((subIntfObj.Ipv4.Config != nil && *subIntfObj.Ipv4.Config.DhcpClient == true) || (entry.IsPopulated() && entry.Has("ipv4_dhcp_client") && entry.Get("ipv4_dhcp_client") == "true")) { + errStr := "Static IPV4 address can't be configured when IPV4 DHCP client is enabled on the interface " + ifName + log.Info("YangToDb_intf_subintf_ip_xfmr : " + errStr) + return subIntfmap, errors.New(errStr) + } for ip, _ := range subIntfObj.Ipv4.Addresses.Address { addr := subIntfObj.Ipv4.Addresses.Address[ip] if addr.Config != nil { @@ -986,6 +1084,11 @@ var YangToDb_intf_ip_addr_xfmr SubTreeXfmrYangToDb = func(inParams XfmrParams) ( } } if subIntfObj.Ipv6 != nil && subIntfObj.Ipv6.Addresses != nil { + if intfType == IntfTypeMgmt && len(subIntfObj.Ipv6.Addresses.Address) > 0 && ((subIntfObj.Ipv6.Config != nil && *subIntfObj.Ipv6.Config.DhcpClient == true) || (entry.IsPopulated() && entry.Has("ipv6_dhcp_client") && entry.Get("ipv6_dhcp_client") == "true")) { + errStr := "Static IPV6 address can't be configured when IPV6 DHCP client is enabled on the interface " + ifName + log.Info("YangToDb_intf_subintf_ip_xfmr : " + errStr) + return subIntfmap, errors.New(errStr) + } for ip, _ := range subIntfObj.Ipv6.Addresses.Address { addr := subIntfObj.Ipv6.Addresses.Address[ip] if addr.Config != nil { @@ -1203,7 +1306,7 @@ func getIntfIpByName(dbCl *db.DB, tblName string, ifName string, ipv4 bool, ipv6 if all == false { ipB, _, _ := net.ParseCIDR(key.Get(1)) if ((validIPv4(ipB.String()) && (ipv4 == false)) || - (validIPv6(ipB.String()) && (ipv6 == false))) { + (validIPv6(ipB.String()) && (ipv6 == false))) { continue } if ip != "" { @@ -1232,43 +1335,122 @@ func handleIntfIPGetByTargetURI (inParams XfmrParams, targetUriPath string, ifNa return errors.New(errStr) } intTbl := IntfTypeTblMap[intfType] + var subIntf *ocbinds.OpenconfigInterfaces_Interfaces_Interface_Subinterfaces_Subinterface + if _, ok := intfObj.Subinterfaces.Subinterface[0]; !ok { + subIntf, err = intfObj.Subinterfaces.NewSubinterface(0) + if err != nil { + log.Error("Creation of subinterface subtree failed!") + return err + } + } + subIntf = intfObj.Subinterfaces.Subinterface[0] + ygot.BuildEmptyTree(subIntf) if strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/ipv4/addresses/address/config") || - strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/openconfig-if-ip:ipv4/addresses/address/config") { - ipMap, err = getIntfIpByName(inParams.dbs[db.ConfigDB], intTbl.cfgDb.intfTN, ifName, true, false, ipAddr) - log.Info("handleIntfIPGetByTargetURI : ipv4 config ipMap - : ", ipMap) - convertIpMapToOC(ipMap, intfObj, false) + strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/openconfig-if-ip:ipv4/addresses/address/config") { + ipMap, err = getIntfIpByName(inParams.dbs[db.ConfigDB], intTbl.cfgDb.intfTN, ifName, true, false, ipAddr) + log.Info("handleIntfIPGetByTargetURI : ipv4 config ipMap - : ", ipMap) + convertIpMapToOC(ipMap, intfObj, false) } else if strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/openconfig-if-ip:ipv6/addresses/address/config") || - strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/ipv6/addresses/address/config") { - ipMap, err = getIntfIpByName(inParams.dbs[db.ConfigDB], intTbl.cfgDb.intfTN, ifName, false, true, ipAddr) - log.Info("handleIntfIPGetByTargetURI : ipv6 config ipMap - : ", ipMap) - convertIpMapToOC(ipMap, intfObj, false) + strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/ipv6/addresses/address/config") { + ipMap, err = getIntfIpByName(inParams.dbs[db.ConfigDB], intTbl.cfgDb.intfTN, ifName, false, true, ipAddr) + log.Info("handleIntfIPGetByTargetURI : ipv6 config ipMap - : ", ipMap) + convertIpMapToOC(ipMap, intfObj, false) } else if strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/ipv4/addresses/address/state") || - strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/openconfig-if-ip:ipv4/addresses/address/state") { - ipMap, err = getIntfIpByName(inParams.dbs[db.ApplDB], intTbl.appDb.intfTN, ifName, true, false, ipAddr) - log.Info("handleIntfIPGetByTargetURI : ipv4 state ipMap - : ", ipMap) - convertIpMapToOC(ipMap, intfObj, true) + strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/openconfig-if-ip:ipv4/addresses/address/state") { + ipMap, err = getIntfIpByName(inParams.dbs[db.ApplDB], intTbl.appDb.intfTN, ifName, true, false, ipAddr) + log.Info("handleIntfIPGetByTargetURI : ipv4 state ipMap - : ", ipMap) + convertIpMapToOC(ipMap, intfObj, true) } else if strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/openconfig-if-ip:ipv6/addresses/address/state") || - strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/ipv6/addresses/address/state") { - ipMap, err = getIntfIpByName(inParams.dbs[db.ApplDB], intTbl.appDb.intfTN, ifName, false, true, ipAddr) - log.Info("handleIntfIPGetByTargetURI : ipv6 state ipMap - : ", ipMap) - convertIpMapToOC(ipMap, intfObj, true) + strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/ipv6/addresses/address/state") { + ipMap, err = getIntfIpByName(inParams.dbs[db.ApplDB], intTbl.appDb.intfTN, ifName, false, true, ipAddr) + log.Info("handleIntfIPGetByTargetURI : ipv6 state ipMap - : ", ipMap) + convertIpMapToOC(ipMap, intfObj, true) } else if strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/ipv4/addresses") || - strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/openconfig-if-ip:ipv4/addresses") { + strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/openconfig-if-ip:ipv4/addresses") { ipMap, err = getIntfIpByName(inParams.dbs[db.ConfigDB], intTbl.cfgDb.intfTN, ifName, true, false, ipAddr) - log.Info("handleIntfIPGetByTargetURI : ipv4 config ipMap - : ", ipMap) + log.Info("handleIntfIPGetByTargetURI : ipv4 config ipMap - : ", ipMap) convertIpMapToOC(ipMap, intfObj, false) ipMap, err = getIntfIpByName(inParams.dbs[db.ApplDB], intTbl.appDb.intfTN, ifName, true, false, ipAddr) - log.Info("handleIntfIPGetByTargetURI : ipv4 state ipMap - : ", ipMap) + log.Info("handleIntfIPGetByTargetURI : ipv4 state ipMap - : ", ipMap) convertIpMapToOC(ipMap, intfObj, true) } else if strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/ipv6/addresses") || - strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/openconfig-if-ip:ipv6/addresses") { + strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/openconfig-if-ip:ipv6/addresses") { ipMap, err = getIntfIpByName(inParams.dbs[db.ConfigDB], intTbl.cfgDb.intfTN, ifName, false, true, ipAddr) - log.Info("handleIntfIPGetByTargetURI : ipv6 config ipMap - : ", ipMap) + log.Info("handleIntfIPGetByTargetURI : ipv6 config ipMap - : ", ipMap) convertIpMapToOC(ipMap, intfObj, false) ipMap, err = getIntfIpByName(inParams.dbs[db.ApplDB], intTbl.appDb.intfTN, ifName, false, true, ipAddr) - log.Info("handleIntfIPGetByTargetURI : ipv6 state ipMap - : ", ipMap) + log.Info("handleIntfIPGetByTargetURI : ipv6 state ipMap - : ", ipMap) convertIpMapToOC(ipMap, intfObj, true) + } else if strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/ipv4/config") || + strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/openconfig-if-ip:ipv4/config") { + entry, dbErr := inParams.dbs[db.ConfigDB].GetEntry(&db.TableSpec{Name:intTbl.cfgDb.intfTN}, db.Key{Comp: []string{ifName}}) + if dbErr == nil { + if entry.Has("ipv4_default_gwaddr") { + subIntf.Ipv4.Config.DefaultGwaddr = new(string) + *subIntf.Ipv4.Config.DefaultGwaddr = entry.Get("ipv4_default_gwaddr") + } + if entry.Has("ipv4_dhcp_client") { + subIntf.Ipv4.Config.DhcpClient = new(bool) + if entry.Get("ipv4_dhcp_client") == "true" { + *subIntf.Ipv4.Config.DhcpClient = true + } else { + *subIntf.Ipv4.Config.DhcpClient = false + } + } + } + } else if strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/ipv6/config") || + strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/openconfig-if-ip:ipv6/config") { + entry, dbErr := inParams.dbs[db.ConfigDB].GetEntry(&db.TableSpec{Name:intTbl.cfgDb.intfTN}, db.Key{Comp: []string{ifName}}) + if dbErr == nil { + if entry.Has("ipv6_default_gwaddr") { + subIntf.Ipv6.Config.DefaultGwaddr = new(string) + *subIntf.Ipv6.Config.DefaultGwaddr = entry.Get("ipv6_default_gwaddr") + } + if entry.Has("ipv6_dhcp_client") { + subIntf.Ipv6.Config.DhcpClient = new(bool) + if entry.Get("ipv6_dhcp_client") == "true" { + *subIntf.Ipv6.Config.DhcpClient = true + } else { + *subIntf.Ipv6.Config.DhcpClient = false + } + } + } + + } else if strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/ipv4/state") || + strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/openconfig-if-ip:ipv4/state") { + entry, dbErr := inParams.dbs[db.ApplDB].GetEntry(&db.TableSpec{Name:intTbl.appDb.intfTN}, db.Key{Comp: []string{ifName}}) + if dbErr == nil { + if entry.Has("ipv4_default_gwaddr") { + subIntf.Ipv4.State.DefaultGwaddr = new(string) + *subIntf.Ipv4.State.DefaultGwaddr = entry.Get("ipv4_default_gwaddr") + } + if entry.Has("ipv4_dhcp_client") { + subIntf.Ipv4.State.DhcpClient = new(bool) + if entry.Get("ipv4_dhcp_client") == "true" { + *subIntf.Ipv4.State.DhcpClient = true + } else { + *subIntf.Ipv4.State.DhcpClient = false + } + } + } + } else if strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/ipv6/state") || + strings.HasPrefix(targetUriPath, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/openconfig-if-ip:ipv6/state") { + entry, dbErr := inParams.dbs[db.ApplDB].GetEntry(&db.TableSpec{Name:intTbl.appDb.intfTN}, db.Key{Comp: []string{ifName}}) + if dbErr == nil { + if entry.Has("ipv6_default_gwaddr") { + subIntf.Ipv6.State.DefaultGwaddr = new(string) + *subIntf.Ipv6.State.DefaultGwaddr = entry.Get("ipv6_default_gwaddr") + } + if entry.Has("ipv6_dhcp_client") { + subIntf.Ipv6.State.DhcpClient = new(bool) + if entry.Get("ipv6_dhcp_client") == "true" { + *subIntf.Ipv6.State.DhcpClient = true + } else { + *subIntf.Ipv6.State.DhcpClient = false + } + } + } } return err } @@ -1729,9 +1911,9 @@ var DbToYang_intf_get_counters_xfmr SubTreeXfmrDbToYang = func(inParams XfmrPara } intTbl := IntfTypeTblMap[intfType] if intTbl.CountersHdl.PopulateCounters == nil { - log.Infof("Counters for Interface: %s not supported!", intfName) - return nil - } + log.Infof("Counters for Interface: %s not supported!", intfName) + return nil + } var state_counters * ocbinds.OpenconfigInterfaces_Interfaces_Interface_State_Counters if intfsObj != nil && intfsObj.Interface != nil && len(intfsObj.Interface) > 0 { @@ -1793,58 +1975,58 @@ var YangToDb_intf_eth_port_config_xfmr SubTreeXfmrYangToDb = func(inParams XfmrP tblName, _ := getMemTableNameByDBId(intTbl, inParams.curDb) var lagStr string switch inParams.oper { - case CREATE: - case UPDATE: - log.Info("Add member port") - lagId := intfObj.Ethernet.Config.AggregateId - lagStr = "PortChannel" + (*lagId) - /* Check if PortChannel exists */ - err = validateLagExists(inParams.d, &intTbl.cfgDb.portTN, &lagStr) - if err != nil { - errStr := "Invalid PortChannel: " + lagStr - err = tlerr.InvalidArgsError{Format: errStr} - return nil, err - } - /* Check if given iface already part of a PortChannel */ - lagKeys, err := inParams.d.GetKeys(&db.TableSpec{Name:tblName}) - if err == nil { - for i, _ := range lagKeys { - if ifName == lagKeys[i].Get(1) { - errStr := "Given interface already part of " + lagKeys[i].Get(0) - err = tlerr.InvalidArgsError{Format: errStr} - return nil, err - } - } - } - /* Check if L3 configs present on given physical interface */ - err = validateL3ConfigExists(inParams.d, &ifName) - if err != nil { - return nil, err - } - - case DELETE: - log.Info("Delete member port") - lagKeys, err := inParams.d.GetKeys(&db.TableSpec{Name:tblName}) - /* Find the port-channel the given ifname is part of */ - if err != nil { - log.Info("No entries in PORTCHANNEL_MEMBER TABLE") - return nil, errors.New("No entries in PORTCHANNEL_MEMBER TABLE") - } - var flag bool = false + case CREATE: + case UPDATE: + log.Info("Add member port") + lagId := intfObj.Ethernet.Config.AggregateId + lagStr = "PortChannel" + (*lagId) + /* Check if PortChannel exists */ + err = validateLagExists(inParams.d, &intTbl.cfgDb.portTN, &lagStr) + if err != nil { + errStr := "Invalid PortChannel: " + lagStr + err = tlerr.InvalidArgsError{Format: errStr} + return nil, err + } + /* Check if given iface already part of a PortChannel */ + lagKeys, err := inParams.d.GetKeys(&db.TableSpec{Name:tblName}) + if err == nil { for i, _ := range lagKeys { if ifName == lagKeys[i].Get(1) { - log.Info("Found Entry in PORTCHANNEL_MEMBER TABLE") - flag = true - lagStr = lagKeys[i].Get(0) - log.Info("Given interface part of PortChannel", lagStr) - break + errStr := "Given interface already part of " + lagKeys[i].Get(0) + err = tlerr.InvalidArgsError{Format: errStr} + return nil, err } } - if flag == false { - log.Info("Given Interface not part of any PortChannel") - err = errors.New("Given Interface not part of any PortChannel") - return nil, err + } + /* Check if L3 configs present on given physical interface */ + err = validateL3ConfigExists(inParams.d, &ifName) + if err != nil { + return nil, err + } + + case DELETE: + log.Info("Delete member port") + lagKeys, err := inParams.d.GetKeys(&db.TableSpec{Name:tblName}) + /* Find the port-channel the given ifname is part of */ + if err != nil { + log.Info("No entries in PORTCHANNEL_MEMBER TABLE") + return nil, errors.New("No entries in PORTCHANNEL_MEMBER TABLE") + } + var flag bool = false + for i, _ := range lagKeys { + if ifName == lagKeys[i].Get(1) { + log.Info("Found Entry in PORTCHANNEL_MEMBER TABLE") + flag = true + lagStr = lagKeys[i].Get(0) + log.Info("Given interface part of PortChannel", lagStr) + break } + } + if flag == false { + log.Info("Given Interface not part of any PortChannel") + err = errors.New("Given Interface not part of any PortChannel") + return nil, err + } }/* End of switch case */ m := make(map[string]string) value := db.Value{Field: m} @@ -1990,15 +2172,15 @@ var DbToYang_neigh_tbl_get_all_ipv4_xfmr SubTreeXfmrDbToYang = func (inParams Xf } /*The transformer returns complete table regardless of the interface. - First check if the interface and IP of this redis entry matches one - available in the received URI + First check if the interface and IP of this redis entry matches one + available in the received URI */ if (strings.Contains(targetUriPath, "ipv4") && addrFamily != "IPv4") || - intfName != intfNameRcvd || - (ipAddrRcvd != "" && ipAddrRcvd != ipAddr) { - log.Info("Skipping entry: ", entry, "for interface: ", intfName, " and IP:", ipAddr, - "interface received: ", intfNameRcvd, " IP received: ", ipAddrRcvd) - continue + intfName != intfNameRcvd || + (ipAddrRcvd != "" && ipAddrRcvd != ipAddr) { + log.Info("Skipping entry: ", entry, "for interface: ", intfName, " and IP:", ipAddr, + "interface received: ", intfNameRcvd, " IP received: ", ipAddrRcvd) + continue } else if strings.HasPrefix(targetUriPath, NEIGH_IPv4_PREFIX_STATE_LL) { if neighObj, ok = subIntfObj.Ipv4.Neighbors.Neighbor[ipAddr]; !ok { neighObj, err = subIntfObj.Ipv4.Neighbors.NewNeighbor(ipAddr) @@ -2109,11 +2291,11 @@ var DbToYang_neigh_tbl_get_all_ipv6_xfmr SubTreeXfmrDbToYang = func (inParams Xf } if (strings.Contains(targetUriPath, "ipv6") && addrFamily != "IPv6") || - intfName != intfNameRcvd || - (ipAddrRcvd != "" && ipAddrRcvd != ipAddr) { - log.Info("Skipping entry: ", entry, "for interface: ", intfName, " and IP:", ipAddr, - "interface received: ", intfNameRcvd, " IP received: ", ipAddrRcvd) - continue + intfName != intfNameRcvd || + (ipAddrRcvd != "" && ipAddrRcvd != ipAddr) { + log.Info("Skipping entry: ", entry, "for interface: ", intfName, " and IP:", ipAddr, + "interface received: ", intfNameRcvd, " IP received: ", ipAddrRcvd) + continue }else if strings.HasPrefix(targetUriPath, NEIGH_IPv6_PREFIX_STATE_LL) { if neighObj, ok = subIntfObj.Ipv6.Neighbors.Neighbor[ipAddr]; !ok { neighObj, err = subIntfObj.Ipv6.Neighbors.NewNeighbor(ipAddr) From aeb708c460f8953c09aa59be664acbbff4b3209e Mon Sep 17 00:00:00 2001 From: Ravi Vasanthm Date: Wed, 8 Jan 2020 11:52:17 -0800 Subject: [PATCH 2/7] Added dhcp, default gateway and renew dhcp clitree and actioner methods and needed yang models changes. --- .../sonic-mgmt-interface-annot.yang | 16 ++++++ models/yang/sonic/sonic-mgmt-interface.yang | 26 +++++++++ src/CLI/actioner/sonic-cli-if.py | 46 ++++++++++++++- src/CLI/actioner/sonic-cli-mgmt-dhcp.py | 53 +++++++++++++++++ src/CLI/clitree/cli-xml/enable_mode.xml | 4 ++ src/CLI/clitree/cli-xml/ipv4.xml | 50 ++++++++++++++-- src/CLI/clitree/cli-xml/ipv6.xml | 41 +++++++++++++ src/CLI/clitree/cli-xml/mgmt_dhcp.xml | 57 +++++++++++++++++++ src/translib/transformer/xfmr_intf.go | 10 +++- 9 files changed, 294 insertions(+), 9 deletions(-) create mode 100644 models/yang/annotations/sonic-mgmt-interface-annot.yang create mode 100644 src/CLI/actioner/sonic-cli-mgmt-dhcp.py create mode 100644 src/CLI/clitree/cli-xml/mgmt_dhcp.xml diff --git a/models/yang/annotations/sonic-mgmt-interface-annot.yang b/models/yang/annotations/sonic-mgmt-interface-annot.yang new file mode 100644 index 0000000000..e840c44e5d --- /dev/null +++ b/models/yang/annotations/sonic-mgmt-interface-annot.yang @@ -0,0 +1,16 @@ +module sonic-mgmt-interface-annot { + + yang-version "1.1"; + + namespace "http://openconfig.net/yang/annotation/smgmt-intf-annot"; + prefix "smgmt-intf-annot"; + + import sonic-extensions { prefix sonic-ext; } + import sonic-mgmt-interface { prefix smgmt-intf; } + + deviation /smgmt-intf:renew_dhcp_lease { + deviate add { + sonic-ext:rpc-callback "rpc_renew_dhcp_lease"; + } + } +} diff --git a/models/yang/sonic/sonic-mgmt-interface.yang b/models/yang/sonic/sonic-mgmt-interface.yang index f095aa1c79..99b4c02168 100644 --- a/models/yang/sonic/sonic-mgmt-interface.yang +++ b/models/yang/sonic/sonic-mgmt-interface.yang @@ -31,6 +31,32 @@ module sonic-mgmt-interface { "Initial revision."; } +/* + * RPC's + */ + rpc renew_dhcp_lease { + description "RPC for renew DHCP lease of an interface."; + input { + leaf portname{ + type leafref { + path "/mgmtprt:sonic-mgmt-port/mgmtprt:MGMT_PORT/mgmtprt:MGMT_PORT_LIST/mgmtprt:ifname"; + } + } + } + output { + leaf status { + type int32; + description + "The status of the operation execution request."; + } + leaf status-detail { + type string; + description + "The detailed status of the operation execution request."; + } + } + } + container sonic-mgmt-interface { container MGMT_INTERFACE { diff --git a/src/CLI/actioner/sonic-cli-if.py b/src/CLI/actioner/sonic-cli-if.py index 51242ab50e..65df6b53e7 100755 --- a/src/CLI/actioner/sonic-cli-if.py +++ b/src/CLI/actioner/sonic-cli-if.py @@ -95,8 +95,50 @@ def invoke_api(func, args=[]): body = { "openconfig-if-ip:config": {"ip" : sp[0], "prefix-length" : int(sp[1]), "openconfig-interfaces-ext:gw-addr": args[2]} } else: body = { "openconfig-if-ip:config": {"ip" : sp[0], "prefix-length" : int(sp[1])} } - return api.patch(path, body) - + return api.patch(path, body) + + elif func == 'patch_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv4_config_default_gwaddr': + path = cc.Path('/restconf/data/openconfig-interfaces:interfaces/interface={name}/subinterfaces/subinterface={index}/openconfig-if-ip:ipv4/config', name=args[0], index="0") + body = { "openconfig-if-ip:config": {"openconfig-interfaces-ext:default-gwaddr": args[1]}} + return api.patch(path, body) + + elif func == 'delete_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv4_config_default_gwaddr': + path = cc.Path('/restconf/data/openconfig-interfaces:interfaces/interface={name}/subinterfaces/subinterface={index}/openconfig-if-ip:ipv4/config/openconfig-interfaces-ext:default-gwaddr', name=args[0], index="0") + return api.delete(path) + + elif func == 'patch_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv4_config_dhcp_client': + path = cc.Path('/restconf/data/openconfig-interfaces:interfaces/interface={name}/subinterfaces/subinterface={index}/openconfig-if-ip:ipv4/config', name=args[0], index="0") + if args[1] == "true": + body = { "openconfig-if-ip:config": {"openconfig-interfaces-ext:dhcp-client": True }} + else : + body = { "openconfig-if-ip:config": {"openconfig-interfaces-ext:dhcp-client": False }} + return api.patch(path, body) + + elif func == 'delete_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv4_config_dhcp_client': + path = cc.Path('/restconf/data/openconfig-interfaces:interfaces/interface={name}/subinterfaces/subinterface={index}/openconfig-if-ip:ipv4/config/dhcp-client', name=args[0], index="0") + return api.delete(path) + + elif func == 'patch_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv6_config_dhcp_client': + path = cc.Path('/restconf/data/openconfig-interfaces:interfaces/interface={name}/subinterfaces/subinterface={index}/openconfig-if-ip:ipv6/config', name=args[0], index="0") + if args[1] == "true": + body = { "openconfig-if-ip:config": {"openconfig-interfaces-ext:dhcp-client": True }} + else : + body = { "openconfig-if-ip:config": {"openconfig-interfaces-ext:dhcp-client": False }} + return api.patch(path, body) + + elif func == 'delete_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv6_config_dhcp_client': + path = cc.Path('/restconf/data/openconfig-interfaces:interfaces/interface={name}/subinterfaces/subinterface={index}/openconfig-if-ip:ipv6/config/dhcp-client', name=args[0], index="0") + return api.delete(path) + + elif func == 'patch_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv6_config_default_gwaddr': + path = cc.Path('/restconf/data/openconfig-interfaces:interfaces/interface={name}/subinterfaces/subinterface={index}/openconfig-if-ip:ipv6/config', name=args[0], index="0") + body = { "openconfig-if-ip:config": {"openconfig-interfaces-ext:default-gwaddr": args[1]}} + return api.patch(path, body) + + elif func == 'delete_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv6_config_default_gwaddr': + path = cc.Path('/restconf/data/openconfig-interfaces:interfaces/interface={name}/subinterfaces/subinterface={index}/openconfig-if-ip:ipv6/config/openconfig-interfaces-ext:default-gwaddr', name=args[0], index="0") + return api.delete(path) + elif func == 'patch_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv6_addresses_address_config': sp = args[1].split('/') diff --git a/src/CLI/actioner/sonic-cli-mgmt-dhcp.py b/src/CLI/actioner/sonic-cli-mgmt-dhcp.py new file mode 100644 index 0000000000..16d9f32228 --- /dev/null +++ b/src/CLI/actioner/sonic-cli-mgmt-dhcp.py @@ -0,0 +1,53 @@ +#!/usr/bin/python +########################################################################### +# +# Copyright 2019 Dell, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +########################################################################### + +import sys +import time +import json +import ast +import cli_client as cc +from rpipe_utils import pipestr +from scripts.render_cli import show_cli_output + +def invoke(func, args): + body = None + aa = cc.ApiClient() + if func == 'rpc_sonic_mgmt_interface_renew_dhcp_lease': + keypath = cc.Path('/restconf/operations/sonic-mgmt-interface:renew_dhcp_lease') + body = {"sonic-mgmt-interface:input":{"portname":args[0]}} + return aa.post(keypath, body) + else: + return + +def run(func, args): + try: + api_response = invoke(func,args) + status = api_response.content["sonic-mgmt-interface:output"] + if status["status"] != 0: + print status["status-detail"] + except: + print "%Error: Transaction Failure" + return + + +if __name__ == '__main__': + pipestr().write(sys.argv) + run(sys.argv[1], sys.argv[2:]) + + diff --git a/src/CLI/clitree/cli-xml/enable_mode.xml b/src/CLI/clitree/cli-xml/enable_mode.xml index df8673660e..4556fc2300 100644 --- a/src/CLI/clitree/cli-xml/enable_mode.xml +++ b/src/CLI/clitree/cli-xml/enable_mode.xml @@ -67,6 +67,10 @@ limitations under the License. + + @@ -250,9 +250,51 @@ limitations under the License. name="addr" help="IP address" ptype="IP_ADDR" /> - - python $SONIC_CLI_ROOT/sonic-cli-if.py delete_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv4_addresses_address_config_prefix_length ${iface} ${addr} - + + python $SONIC_CLI_ROOT/sonic-cli-if.py delete_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv4_addresses_address_config_prefix_length ${iface} ${addr} + + + + + + + python $SONIC_CLI_ROOT/sonic-cli-if.py patch_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv4_config_default_gwaddr ${iface} ${default-gwaddr} + + + + + python $SONIC_CLI_ROOT/sonic-cli-if.py delete_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv4_config_default_gwaddr ${iface} + + + + + + python $SONIC_CLI_ROOT/sonic-cli-if.py patch_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv4_config_dhcp_client ${iface} true + + + + + python $SONIC_CLI_ROOT/sonic-cli-if.py delete_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv4_config_dhcp_client ${iface} + diff --git a/src/CLI/clitree/cli-xml/ipv6.xml b/src/CLI/clitree/cli-xml/ipv6.xml index a7ab06c70d..912020222f 100644 --- a/src/CLI/clitree/cli-xml/ipv6.xml +++ b/src/CLI/clitree/cli-xml/ipv6.xml @@ -95,6 +95,47 @@ limitations under the License. ptype="IPV6_ADDR" /> python $SONIC_CLI_ROOT/sonic-cli-if.py delete_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv6_addresses_address_config_prefix_length ${iface} ${addr} + + + + python $SONIC_CLI_ROOT/sonic-cli-if.py patch_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv6_config_default_gwaddr ${iface} ${default-gwaddr} + + + + + python $SONIC_CLI_ROOT/sonic-cli-if.py delete_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv6_config_default_gwaddr ${iface} + + + + + + python $SONIC_CLI_ROOT/sonic-cli-if.py patch_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv6_config_dhcp_client ${iface} true + + + + + python $SONIC_CLI_ROOT/sonic-cli-if.py delete_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv6_config_dhcp_client ${iface} + + diff --git a/src/CLI/clitree/cli-xml/mgmt_dhcp.xml b/src/CLI/clitree/cli-xml/mgmt_dhcp.xml new file mode 100644 index 0000000000..3b3a3f23ed --- /dev/null +++ b/src/CLI/clitree/cli-xml/mgmt_dhcp.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + python $SONIC_CLI_ROOT/sonic-cli-mgmt-dhcp.py rpc_sonic_mgmt_interface_renew_dhcp_lease ${mgmt-if-id} + + + + + diff --git a/src/translib/transformer/xfmr_intf.go b/src/translib/transformer/xfmr_intf.go index 4446d16f53..0d011ce0db 100644 --- a/src/translib/transformer/xfmr_intf.go +++ b/src/translib/transformer/xfmr_intf.go @@ -783,6 +783,9 @@ func intf_ip_addr_del (d *db.DB , ifName string, tblName string, subIntf *ocbind if subIntf.Ipv4.Config.DhcpClient != nil { value.Set("ipv4_dhcp_client", "") } + } else { + value.Set("ipv4_default_gwaddr", "") + value.Set("ipv4_dhcp_client", "") } if subIntf.Ipv6 != nil && subIntf.Ipv6.Config != nil { if subIntf.Ipv6.Config.DefaultGwaddr != nil { @@ -791,6 +794,9 @@ func intf_ip_addr_del (d *db.DB , ifName string, tblName string, subIntf *ocbind if subIntf.Ipv6.Config.DhcpClient != nil { value.Set("ipv6_dhcp_client", "") } + } else { + value.Set("ipv6_default_gwaddr", "") + value.Set("ipv6_dhcp_client", "") } subIntfmap[tblName][ifName] = value } @@ -856,9 +862,7 @@ func intf_ip_addr_del (d *db.DB , ifName string, tblName string, subIntf *ocbind IntfMap := IntfMapObj.Field if len(IntfMap) == 1 { if _, ok := IntfMap["NULL"]; ok { - if _, ok := subIntfmap[tblName][ifName]; !ok { - subIntfmap[tblName][ifName] = data - } + subIntfmap[tblName][ifName] = data } } } From dd05006bf33080b72b4a8935f9801bb8a5740c7f Mon Sep 17 00:00:00 2001 From: Ravi Vasanthm Date: Wed, 8 Jan 2020 16:03:39 -0800 Subject: [PATCH 3/7] Added host module to handle dhcp lease renew command and transformer method to dhcp lease renew rpc. --- scripts/host_modules/renew_dhcp_lease.py | 62 +++++++++++++++++++ src/translib/transformer/xfmr_intf.go | 76 ++++++++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 scripts/host_modules/renew_dhcp_lease.py diff --git a/scripts/host_modules/renew_dhcp_lease.py b/scripts/host_modules/renew_dhcp_lease.py new file mode 100644 index 0000000000..8534fc965e --- /dev/null +++ b/scripts/host_modules/renew_dhcp_lease.py @@ -0,0 +1,62 @@ +""" Renew DHCP lease handler""" +import host_service +import subprocess + +MOD_NAME= 'renew_dhcp_lease' + +class RENEW_DHCP_LEASE(host_service.HostModule): + """DBus endpoint that executes RENEW_DHCP_LEASE related commands """ + + @staticmethod + def _run_command(commands, options): + """ Run renew dhcp lease command """ + if len(options) < 2: + print("RENEW_DHCP_LEASE Invalid options, {}".format(options)) + return 1, "Invalid options" + + ifName = options[0] + version = "-4" + file_ext = "4" + output = "" + try: + for x in options[1:]: + if x == "ipv4": + version = "-4" + file_ext = "4" + + elif x == "ipv6": + version = "-6" + file_ext = "6" + else: + continue + + cmd = "/sbin/dhclient {} -r {}".format(version, ifName) + print("RENEW_DHCP_LEASE - cmd {}".format(cmd)) + output = subprocess.check_output(cmd) + print('RENEW_DHCP_LEASE release Output -> ', output) + + cmd = "[ -f /var/run/dhclient{}.{}.pid ] && kill `cat /var/run/dhclient{}.{}.pid` && rm -f /var/run/dhclient{}.{}.pid".format(file_ext, ifName, file_ext, ifName, file_ext, ifName) + print("RENEW_DHCP_LEASE - cmd {}".format(cmd)) + output = subprocess.check_output(cmd) + print('RENEW_DHCP_LEASE release Output -> ', output) + + cmd = "/sbin/dhclient {} -pf /run/dhclient{}.{}.pid -lf /var/lib/dhcp/dhclient{}.{}.leases {} -nw -D LL".format(version, file_ext, ifName, file_ext, ifName, ifName) + print("RENEW_DHCP_LEASE - cmd {}".format(cmd)) + output = subprocess.check_output(cmd) + print('RENEW_DHCP_LEASE Output -> ', output) + + except subprocess.CalledProcessError as err: + print("Exception when calling get_sonic_error -> %s\n" %(err)) + rc = err.returncode + output = err.output + + return rc,output + + + @host_service.method(host_service.bus_name(MOD_NAME), in_signature='as', out_signature='is') + def action(self, options): + return RENEW_DHCP_LEASE._run_command(options) + +def register(): + """Return class name""" + return RENEW_DHCP_LEASE, MOD_NAME diff --git a/src/translib/transformer/xfmr_intf.go b/src/translib/transformer/xfmr_intf.go index 0d011ce0db..c42c36a08c 100644 --- a/src/translib/transformer/xfmr_intf.go +++ b/src/translib/transformer/xfmr_intf.go @@ -62,6 +62,7 @@ func init () { XlateFuncBind("YangToDb_neigh_tbl_key_xfmr", YangToDb_neigh_tbl_key_xfmr) /*--show ip ARP/neighbors changes end--*/ XlateFuncBind("rpc_clear_counters", rpc_clear_counters) + XlateFuncBind("rpc_renew_dhcp_lease", rpc_renew_dhcp_lease) } /*--show ip ARP/neighbors changes start--*/ @@ -257,6 +258,81 @@ func performIfNameKeyXfmrOp(inParams *XfmrParams, requestUriPath *string, ifName } return err } +/* RPC for DHCP lease renew */ + +var rpc_renew_dhcp_lease RpcCallpoint = func(body []byte, dbs [db.MaxDB]*db.DB) ([]byte, error) { + var err error + var result struct { + Output struct { + Status int32 `json:"status"` + Status_detail string`json:"status-detail"` + } `json:"sonic-interface:output"` + } + + result.Output.Status = 1 + /* Unmarshal input data */ + var mapData map[string]interface{} + err= json.Unmarshal(body, &mapData) + if err != nil { + log.Info("Failed to unmarshall given input data") + result.Output.Status_detail = fmt.Sprintf("Error: Failed to unmarshall given input data") + return json.Marshal(&result) + } + input, _ := mapData["sonic-mgmt-interface:input"] + mapData = input.(map[string]interface{}) + portname := mapData["portname"] + ifName := portname.(string) + log.Info("rpc_renew_dhcp_lease: intfName: ", ifName) + + intfType, _, ierr := getIntfTypeByName(ifName) + if ierr != nil || intfType != IntfTypeMgmt { + log.Errorf("Extracting Interface type for Interface: %s failed or not supported!", ifName) + result.Output.Status_detail = fmt.Sprintf("Error: Not supported for interface " + ifName) + return json.Marshal(&result) + } + + intTbl := IntfTypeTblMap[intfType] + tblName, _ := getIntfTableNameByDBId(intTbl, db.ConfigDB) + entry, dbErr := dbs[db.ConfigDB].GetEntry(&db.TableSpec{Name:tblName}, db.Key{Comp: []string{ifName}}) + if dbErr != nil || !entry.IsPopulated() { + log.Errorf("Interface config not found or not populated: %s failed!", ifName) + result.Output.Status_detail = fmt.Sprintf("Error: DHCP client not enabled for interface " + ifName) + return json.Marshal(&result) + } + + var options []string + options = append(options, ifName) + ipv4_dhcp := false + ipv6_dhcp := false + if entry.Has("ipv4_dhcp_client") && entry.Get("ipv4_dhcp_client") == "true" { + ipv4_dhcp = true + options = append(options, "ipv4") + } + if entry.Has("ipv6_dhcp_client") && entry.Get("ipv6_dhcp_client") == "true" { + ipv6_dhcp = true + options = append(options, "ipv6") + } + if (ipv4_dhcp == false && ipv6_dhcp == false) || (len(options) < 2) { + log.Errorf("DHCP IPv4 and IPv6 client not enabled for interface " + ifName) + result.Output.Status_detail = fmt.Sprintf("Error: DHCP client not enabled for interface " + ifName) + return json.Marshal(&result) + } + + log.Info("rpc_renew_dhcp_lease: Command:", options) + + query_result := hostQuery("renew_dhcp_lease.action", options) + + if query_result.Err != nil { + result.Output.Status_detail = "ERROR:Internal SONiC Hostservice communication failure." + } else if query_result.Body[0].(int32) != 0 { + result.Output.Status_detail = fmt.Sprintf("ERROR:Invalid renew DHCP lease request " + ifName) + } else { + result.Output.Status = 0 + result.Output.Status_detail = "Success: Renew DHCP lease" + } + return json.Marshal(&result) +} + /* RPC for clear counters */ var rpc_clear_counters RpcCallpoint = func(body []byte, dbs [db.MaxDB]*db.DB) ([]byte, error) { From 4faf925cdce6846f29340210703b0567ac1c0452 Mon Sep 17 00:00:00 2001 From: Ravi Vasanthm Date: Thu, 9 Jan 2020 10:44:53 -0800 Subject: [PATCH 4/7] Fixed issue found in UT. --- scripts/host_modules/renew_dhcp_lease.py | 25 +++++++++++------------- src/CLI/clitree/cli-xml/mgmt_dhcp.xml | 2 +- src/translib/transformer/xfmr_intf.go | 4 ++-- 3 files changed, 14 insertions(+), 17 deletions(-) diff --git a/scripts/host_modules/renew_dhcp_lease.py b/scripts/host_modules/renew_dhcp_lease.py index 8534fc965e..29a9846e79 100644 --- a/scripts/host_modules/renew_dhcp_lease.py +++ b/scripts/host_modules/renew_dhcp_lease.py @@ -8,41 +8,38 @@ class RENEW_DHCP_LEASE(host_service.HostModule): """DBus endpoint that executes RENEW_DHCP_LEASE related commands """ @staticmethod - def _run_command(commands, options): + def _run_command(options): """ Run renew dhcp lease command """ if len(options) < 2: print("RENEW_DHCP_LEASE Invalid options, {}".format(options)) return 1, "Invalid options" ifName = options[0] - version = "-4" - file_ext = "4" + version = "" + file_ext = "" + cmd_opt = "" output = "" + rc = 0 try: for x in options[1:]: - if x == "ipv4": - version = "-4" - file_ext = "4" - - elif x == "ipv6": + if x == "ipv6": version = "-6" file_ext = "6" - else: - continue + cmd_opt = "-D LL" cmd = "/sbin/dhclient {} -r {}".format(version, ifName) print("RENEW_DHCP_LEASE - cmd {}".format(cmd)) - output = subprocess.check_output(cmd) + output = subprocess.check_call(cmd, shell=True) print('RENEW_DHCP_LEASE release Output -> ', output) cmd = "[ -f /var/run/dhclient{}.{}.pid ] && kill `cat /var/run/dhclient{}.{}.pid` && rm -f /var/run/dhclient{}.{}.pid".format(file_ext, ifName, file_ext, ifName, file_ext, ifName) print("RENEW_DHCP_LEASE - cmd {}".format(cmd)) - output = subprocess.check_output(cmd) + output = subprocess.check_call(cmd, shell=True) print('RENEW_DHCP_LEASE release Output -> ', output) - cmd = "/sbin/dhclient {} -pf /run/dhclient{}.{}.pid -lf /var/lib/dhcp/dhclient{}.{}.leases {} -nw -D LL".format(version, file_ext, ifName, file_ext, ifName, ifName) + cmd = "/sbin/dhclient {} -pf /run/dhclient{}.{}.pid -lf /var/lib/dhcp/dhclient{}.{}.leases {} -nw {} ".format(version, file_ext, ifName, file_ext, ifName, ifName, cmd_opt) print("RENEW_DHCP_LEASE - cmd {}".format(cmd)) - output = subprocess.check_output(cmd) + output = subprocess.check_call(cmd, shell=True) print('RENEW_DHCP_LEASE Output -> ', output) except subprocess.CalledProcessError as err: diff --git a/src/CLI/clitree/cli-xml/mgmt_dhcp.xml b/src/CLI/clitree/cli-xml/mgmt_dhcp.xml index 3b3a3f23ed..b6407e6594 100644 --- a/src/CLI/clitree/cli-xml/mgmt_dhcp.xml +++ b/src/CLI/clitree/cli-xml/mgmt_dhcp.xml @@ -49,7 +49,7 @@ renew dhcp-lease interface management - python $SONIC_CLI_ROOT/sonic-cli-mgmt-dhcp.py rpc_sonic_mgmt_interface_renew_dhcp_lease ${mgmt-if-id} + python $SONIC_CLI_ROOT/sonic-cli-mgmt-dhcp.py rpc_sonic_mgmt_interface_renew_dhcp_lease eth${mgmt-if-id} diff --git a/src/translib/transformer/xfmr_intf.go b/src/translib/transformer/xfmr_intf.go index c42c36a08c..6cc683fe22 100644 --- a/src/translib/transformer/xfmr_intf.go +++ b/src/translib/transformer/xfmr_intf.go @@ -266,7 +266,7 @@ var rpc_renew_dhcp_lease RpcCallpoint = func(body []byte, dbs [db.MaxDB]*db.DB) Output struct { Status int32 `json:"status"` Status_detail string`json:"status-detail"` - } `json:"sonic-interface:output"` + } `json:"sonic-mgmt-interface:output"` } result.Output.Status = 1 @@ -321,7 +321,7 @@ var rpc_renew_dhcp_lease RpcCallpoint = func(body []byte, dbs [db.MaxDB]*db.DB) log.Info("rpc_renew_dhcp_lease: Command:", options) query_result := hostQuery("renew_dhcp_lease.action", options) - + log.Info("rpc_renew_dhcp_lease ", query_result) if query_result.Err != nil { result.Output.Status_detail = "ERROR:Internal SONiC Hostservice communication failure." } else if query_result.Body[0].(int32) != 0 { From 1b3749826a74718865dedcef420f64f4910b0cd7 Mon Sep 17 00:00:00 2001 From: Ravi Vasanthm Date: Thu, 9 Jan 2020 11:00:36 -0800 Subject: [PATCH 5/7] Fixed issue in returning the status from host module script. --- scripts/host_modules/renew_dhcp_lease.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/scripts/host_modules/renew_dhcp_lease.py b/scripts/host_modules/renew_dhcp_lease.py index 29a9846e79..fceb76f873 100644 --- a/scripts/host_modules/renew_dhcp_lease.py +++ b/scripts/host_modules/renew_dhcp_lease.py @@ -28,19 +28,15 @@ def _run_command(options): cmd_opt = "-D LL" cmd = "/sbin/dhclient {} -r {}".format(version, ifName) - print("RENEW_DHCP_LEASE - cmd {}".format(cmd)) output = subprocess.check_call(cmd, shell=True) - print('RENEW_DHCP_LEASE release Output -> ', output) cmd = "[ -f /var/run/dhclient{}.{}.pid ] && kill `cat /var/run/dhclient{}.{}.pid` && rm -f /var/run/dhclient{}.{}.pid".format(file_ext, ifName, file_ext, ifName, file_ext, ifName) - print("RENEW_DHCP_LEASE - cmd {}".format(cmd)) output = subprocess.check_call(cmd, shell=True) - print('RENEW_DHCP_LEASE release Output -> ', output) cmd = "/sbin/dhclient {} -pf /run/dhclient{}.{}.pid -lf /var/lib/dhcp/dhclient{}.{}.leases {} -nw {} ".format(version, file_ext, ifName, file_ext, ifName, ifName, cmd_opt) - print("RENEW_DHCP_LEASE - cmd {}".format(cmd)) output = subprocess.check_call(cmd, shell=True) - print('RENEW_DHCP_LEASE Output -> ', output) + + output = "SUCCESS" except subprocess.CalledProcessError as err: print("Exception when calling get_sonic_error -> %s\n" %(err)) From 43c51e3e4e0b5fabd4eedc5b75458134a3760524 Mon Sep 17 00:00:00 2001 From: Ravi Vasanthm Date: Fri, 10 Jan 2020 14:35:42 -0800 Subject: [PATCH 6/7] Fixed issue in UT and integration testing with hostcfgd and changes related to DHCP default config. --- src/CLI/clitree/cli-xml/ipv4.xml | 27 ++++++++----------- src/CLI/clitree/cli-xml/ipv6.xml | 25 +++++++---------- src/translib/transformer/xfmr_intf.go | 39 +++++++++++---------------- 3 files changed, 37 insertions(+), 54 deletions(-) diff --git a/src/CLI/clitree/cli-xml/ipv4.xml b/src/CLI/clitree/cli-xml/ipv4.xml index c814423508..17269884e4 100644 --- a/src/CLI/clitree/cli-xml/ipv4.xml +++ b/src/CLI/clitree/cli-xml/ipv4.xml @@ -164,7 +164,7 @@ limitations under the License. help="IP address" ptype="IP_ADDR" /> - python $SONIC_CLI_ROOT/sonic-cli-if.py delete_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv4_addresses_address_config_prefix_length ${iface} ${addr} + python $SONIC_CLI_ROOT/sonic_cli_if.py delete_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv4_addresses_address_config_prefix_length ${iface} ${addr} @@ -177,7 +177,7 @@ limitations under the License. ptype="IP_ADDR" /> - python $SONIC_CLI_ROOT/sonic-cli-if.py patch_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv4_config_default_gwaddr ${iface} ${default-gwaddr} + python $SONIC_CLI_ROOT/sonic_cli_if.py patch_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv4_config_default_gwaddr ${iface} ${default-gwaddr} - python $SONIC_CLI_ROOT/sonic-cli-if.py delete_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv4_config_default_gwaddr ${iface} + python $SONIC_CLI_ROOT/sonic_cli_if.py delete_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv4_config_default_gwaddr ${iface} + help="Enable/Disable DHCP client"> - python $SONIC_CLI_ROOT/sonic-cli-if.py patch_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv4_config_dhcp_client ${iface} true - - - - - python $SONIC_CLI_ROOT/sonic-cli-if.py delete_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv4_config_dhcp_client ${iface} + if test "${enable}" = "enable" ; then + python $SONIC_CLI_ROOT/sonic_cli_if.py patch_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv4_config_dhcp_client ${iface} true + else + python $SONIC_CLI_ROOT/sonic_cli_if.py patch_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv4_config_dhcp_client ${iface} false + fi diff --git a/src/CLI/clitree/cli-xml/ipv6.xml b/src/CLI/clitree/cli-xml/ipv6.xml index d15e9453ba..fe2d779dc3 100644 --- a/src/CLI/clitree/cli-xml/ipv6.xml +++ b/src/CLI/clitree/cli-xml/ipv6.xml @@ -104,7 +104,7 @@ limitations under the License. ptype="IPV6_ADDR" /> - python $SONIC_CLI_ROOT/sonic-cli-if.py patch_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv6_config_default_gwaddr ${iface} ${default-gwaddr} + python $SONIC_CLI_ROOT/sonic_cli_if.py patch_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv6_config_default_gwaddr ${iface} ${default-gwaddr} - python $SONIC_CLI_ROOT/sonic-cli-if.py delete_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv6_config_default_gwaddr ${iface} + python $SONIC_CLI_ROOT/sonic_cli_if.py delete_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv6_config_default_gwaddr ${iface} + help="Enable/Disable IPv6 DHCP client"> - python $SONIC_CLI_ROOT/sonic-cli-if.py patch_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv6_config_dhcp_client ${iface} true - - - - - python $SONIC_CLI_ROOT/sonic-cli-if.py delete_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv6_config_dhcp_client ${iface} + if test "${enable}" = "enable" ; then + python $SONIC_CLI_ROOT/sonic_cli_if.py patch_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv6_config_dhcp_client ${iface} true + else + python $SONIC_CLI_ROOT/sonic_cli_if.py patch_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv6_config_dhcp_client ${iface} false + fi diff --git a/src/translib/transformer/xfmr_intf.go b/src/translib/transformer/xfmr_intf.go index d02dd1e77d..35e1bf8453 100644 --- a/src/translib/transformer/xfmr_intf.go +++ b/src/translib/transformer/xfmr_intf.go @@ -276,32 +276,31 @@ var rpc_renew_dhcp_lease RpcCallpoint = func(body []byte, dbs [db.MaxDB]*db.DB) intTbl := IntfTypeTblMap[intfType] tblName, _ := getIntfTableNameByDBId(intTbl, db.ConfigDB) - entry, dbErr := dbs[db.ConfigDB].GetEntry(&db.TableSpec{Name:tblName}, db.Key{Comp: []string{ifName}}) - if dbErr != nil || !entry.IsPopulated() { - log.Errorf("Interface config not found or not populated: %s failed!", ifName) - result.Output.Status_detail = fmt.Sprintf("Error: DHCP client not enabled for interface " + ifName) - return json.Marshal(&result) - } + var entry db.Value + entry, err = dbs[db.ConfigDB].GetEntry(&db.TableSpec{Name:tblName}, db.Key{Comp: []string{ifName}}) var options []string options = append(options, ifName) - ipv4_dhcp := false - ipv6_dhcp := false - if entry.Has("ipv4_dhcp_client") && entry.Get("ipv4_dhcp_client") == "true" { - ipv4_dhcp = true + + if entry.IsPopulated() { + if entry.Has("ipv4_dhcp_client") == false || entry.Get("ipv4_dhcp_client") != "false" { + options = append(options, "ipv4") + } + if entry.Has("ipv6_dhcp_client") == false || entry.Get("ipv6_dhcp_client") != "false" { + options = append(options, "ipv6") + } + } else { options = append(options, "ipv4") - } - if entry.Has("ipv6_dhcp_client") && entry.Get("ipv6_dhcp_client") == "true" { - ipv6_dhcp = true options = append(options, "ipv6") } - if (ipv4_dhcp == false && ipv6_dhcp == false) || (len(options) < 2) { + + log.Info("rpc_renew_dhcp_lease: Command:", options) + if len(options) < 2 { log.Errorf("DHCP IPv4 and IPv6 client not enabled for interface " + ifName) result.Output.Status_detail = fmt.Sprintf("Error: DHCP client not enabled for interface " + ifName) return json.Marshal(&result) } - log.Info("rpc_renew_dhcp_lease: Command:", options) query_result := hostQuery("renew_dhcp_lease.action", options) log.Info("rpc_renew_dhcp_lease ", query_result) @@ -842,9 +841,6 @@ func intf_ip_addr_del (d *db.DB , ifName string, tblName string, subIntf *ocbind if subIntf.Ipv4.Config.DhcpClient != nil { value.Set("ipv4_dhcp_client", "") } - } else { - value.Set("ipv4_default_gwaddr", "") - value.Set("ipv4_dhcp_client", "") } if subIntf.Ipv6 != nil && subIntf.Ipv6.Config != nil { if subIntf.Ipv6.Config.DefaultGwaddr != nil { @@ -853,9 +849,6 @@ func intf_ip_addr_del (d *db.DB , ifName string, tblName string, subIntf *ocbind if subIntf.Ipv6.Config.DhcpClient != nil { value.Set("ipv6_dhcp_client", "") } - } else { - value.Set("ipv6_default_gwaddr", "") - value.Set("ipv6_dhcp_client", "") } subIntfmap[tblName][ifName] = value } @@ -1094,7 +1087,7 @@ var YangToDb_intf_ip_addr_xfmr SubTreeXfmrYangToDb = func(inParams XfmrParams) ( } if subIntfObj.Ipv4 != nil && subIntfObj.Ipv4.Addresses != nil { - if intfType == IntfTypeMgmt && len(subIntfObj.Ipv4.Addresses.Address) > 0 && ((subIntfObj.Ipv4.Config != nil && *subIntfObj.Ipv4.Config.DhcpClient == true) || (entry.IsPopulated() && entry.Has("ipv4_dhcp_client") && entry.Get("ipv4_dhcp_client") == "true")) { + if intfType == IntfTypeMgmt && len(subIntfObj.Ipv4.Addresses.Address) > 0 && ((subIntfObj.Ipv4.Config != nil && *subIntfObj.Ipv4.Config.DhcpClient == true) || !entry.IsPopulated() || entry.Has("ipv4_dhcp_client") == false || entry.Get("ipv4_dhcp_client") == "true") { errStr := "Static IPV4 address can't be configured when IPV4 DHCP client is enabled on the interface " + ifName log.Info("YangToDb_intf_subintf_ip_xfmr : " + errStr) return subIntfmap, errors.New(errStr) @@ -1147,7 +1140,7 @@ var YangToDb_intf_ip_addr_xfmr SubTreeXfmrYangToDb = func(inParams XfmrParams) ( } } if subIntfObj.Ipv6 != nil && subIntfObj.Ipv6.Addresses != nil { - if intfType == IntfTypeMgmt && len(subIntfObj.Ipv6.Addresses.Address) > 0 && ((subIntfObj.Ipv6.Config != nil && *subIntfObj.Ipv6.Config.DhcpClient == true) || (entry.IsPopulated() && entry.Has("ipv6_dhcp_client") && entry.Get("ipv6_dhcp_client") == "true")) { + if intfType == IntfTypeMgmt && len(subIntfObj.Ipv6.Addresses.Address) > 0 && ((subIntfObj.Ipv6.Config != nil && *subIntfObj.Ipv6.Config.DhcpClient == true) || !entry.IsPopulated() || entry.Has("ipv6_dhcp_client") == false || entry.Get("ipv6_dhcp_client") == "true") { errStr := "Static IPV6 address can't be configured when IPV6 DHCP client is enabled on the interface " + ifName log.Info("YangToDb_intf_subintf_ip_xfmr : " + errStr) return subIntfmap, errors.New(errStr) From ac0155eb5c3a2026f894babea0461b33266db61c Mon Sep 17 00:00:00 2001 From: Ravi Vasanthm Date: Wed, 15 Jan 2020 16:16:13 -0800 Subject: [PATCH 7/7] Fixed issue in dhcp renew when dhclient is not running. --- scripts/host_modules/renew_dhcp_lease.py | 30 +++++++++++++++--------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/scripts/host_modules/renew_dhcp_lease.py b/scripts/host_modules/renew_dhcp_lease.py index fceb76f873..e71d90ebec 100644 --- a/scripts/host_modules/renew_dhcp_lease.py +++ b/scripts/host_modules/renew_dhcp_lease.py @@ -20,29 +20,37 @@ def _run_command(options): cmd_opt = "" output = "" rc = 0 - try: - for x in options[1:]: - if x == "ipv6": - version = "-6" - file_ext = "6" - cmd_opt = "-D LL" + for x in options[1:]: + if x == "ipv6": + version = "-6" + file_ext = "6" + cmd_opt = "-D LL" + + try: cmd = "/sbin/dhclient {} -r {}".format(version, ifName) output = subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + print("Exception when calling get_sonic_error -> %s\n" %(err)) + pass + try: cmd = "[ -f /var/run/dhclient{}.{}.pid ] && kill `cat /var/run/dhclient{}.{}.pid` && rm -f /var/run/dhclient{}.{}.pid".format(file_ext, ifName, file_ext, ifName, file_ext, ifName) output = subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + print("Exception when calling get_sonic_error -> %s\n" %(err)) + pass + try: cmd = "/sbin/dhclient {} -pf /run/dhclient{}.{}.pid -lf /var/lib/dhcp/dhclient{}.{}.leases {} -nw {} ".format(version, file_ext, ifName, file_ext, ifName, ifName, cmd_opt) output = subprocess.check_call(cmd, shell=True) output = "SUCCESS" + except subprocess.CalledProcessError as err: + print("Exception when calling get_sonic_error -> %s\n" %(err)) + rc = err.returncode + output = err.output - except subprocess.CalledProcessError as err: - print("Exception when calling get_sonic_error -> %s\n" %(err)) - rc = err.returncode - output = err.output - return rc,output