| /* |
| * Copyright 2022-present Open Networking Foundation |
| * 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. |
| */ |
| |
| package nbi |
| |
| import ( |
| "encoding/json" |
| "net" |
| "net/http" |
| "strconv" |
| "time" |
| |
| app "voltha-go-controller/internal/pkg/application" |
| "voltha-go-controller/log" |
| |
| "github.com/gorilla/mux" |
| ) |
| |
| // DHCPSessionInfoHandle handle dhcp session Requests |
| type DHCPSessionInfoHandle struct { |
| } |
| |
| // DhcpSessionInfo Information |
| type DhcpSessionInfo struct { |
| DeviceID string |
| Uniport string |
| Svlan string |
| Cvlan string |
| UniVlan string |
| MacAddress string |
| IPAddress string |
| Ipv6Address string |
| State string |
| Statev6 string |
| LeaseTime string |
| LeaseTimev6 string |
| } |
| |
| // getDhcpSessionFields returns dhcp session information |
| func getDhcpSessionFields(id string, port string, svlan string, cvlan string, univlan string, macAddr string, ipAddr net.IP, ipv6Addr net.IP, rState app.DhcpRelayState, rStatev6 app.Dhcpv6RelayState, lTime time.Time, l6Time time.Time) *DhcpSessionInfo { |
| ip := ipAddr.String() |
| ipv6 := ipv6Addr.String() |
| relayState := strconv.Itoa(int(rState)) |
| relayStatev6 := strconv.Itoa(int(rStatev6)) |
| leaseTime := (lTime.Format(time.RubyDate)) |
| leasev6Time := (l6Time.Format(time.RubyDate)) |
| dInfo := &DhcpSessionInfo{DeviceID: id, Uniport: port, Svlan: svlan, Cvlan: cvlan, UniVlan: univlan, MacAddress: macAddr, IPAddress: ip, Ipv6Address: ipv6, State: relayState, Statev6: relayStatev6, LeaseTime: leaseTime, LeaseTimev6: leasev6Time} |
| return dInfo |
| } |
| |
| // validateArgs validate the arguments |
| func validateArgs(sv string, cv string, macAddr string, svlan string, cvlan string, mac string) bool { |
| var vlanFlag bool |
| var macFlag bool |
| |
| if ((sv == svlan) || (len(svlan) == 0)) && ((cv == cvlan) || (len(cvlan) == 0)) { |
| vlanFlag = true |
| } |
| |
| if mac == macAddr || len(mac) == 0 { |
| macFlag = true |
| } |
| |
| if macFlag && vlanFlag { |
| return true |
| } |
| return false |
| } |
| |
| // serveHTTP for actions performed on API. |
| func (dh *DHCPSessionInfoHandle) ServeHTTP(w http.ResponseWriter, r *http.Request) { |
| logger.Infow(ctx, "Received-northbound-request", log.Fields{"Method": r.Method, "URL": r.URL}) |
| switch r.Method { |
| case cGet: |
| dh.getDhcpSessionInfo(w, r) |
| default: |
| logger.Warnw(ctx, "Unsupported Method", log.Fields{"Method": r.Method}) |
| } |
| } |
| |
| // getDhcpSessionInfo to retrieve dhcp session information. |
| func (dh *DHCPSessionInfoHandle) getDhcpSessionInfo(w http.ResponseWriter, r *http.Request) { |
| vars := mux.Vars(r) |
| id := vars["id"] |
| mac := vars["mac"] |
| svlan := vars["svlan"] |
| cvlan := vars["cvlan"] |
| var dhcpData *DhcpSessionInfo |
| |
| logger.Infow(ctx, "Received get Dhcp Session Info", log.Fields{"DeviceID": id}) |
| |
| va := app.GetApplication() |
| dhcpSessionInfoResp := []*DhcpSessionInfo{} |
| |
| getPorts := func(key, value interface{}) bool { |
| port := key.(string) |
| vp := value.(*app.VoltPort) |
| |
| // Ignore if UNI port is not UP |
| if vp.State != app.PortStateUp { |
| logger.Warnw(ctx, "Ignore if UNI port is not UP", log.Fields{"VoltPort State": vp.State, "PortStateUp": app.PortStateUp}) |
| return true |
| } |
| |
| // Obtain all VPVs associated with the port |
| vnets, ok := va.VnetsByPort.Load(port) |
| if !ok { |
| return true |
| } |
| |
| for _, vpv := range vnets.([]*app.VoltPortVnet) { |
| // When only device id is provided as argument |
| sv := strconv.Itoa(int(vpv.SVlan)) |
| cv := strconv.Itoa(int(vpv.CVlan)) |
| uv := strconv.Itoa(int(vpv.UniVlan)) |
| macAddr := (vpv.MacAddr).String() |
| |
| validData := validateArgs(sv, cv, macAddr, svlan, cvlan, mac) |
| |
| if validData { |
| dhcpData = getDhcpSessionFields(id, vpv.Port, sv, cv, uv, macAddr, vpv.Ipv4Addr, vpv.Ipv6Addr, vpv.RelayState, vpv.RelayStatev6, vpv.DhcpExpiryTime, vpv.Dhcp6ExpiryTime) |
| dhcpSessionInfoResp = append(dhcpSessionInfoResp, dhcpData) |
| } |
| } |
| return true |
| } |
| |
| if len(id) == 0 { |
| logger.Warnw(ctx, "No Device Id Provided for Dhcp session Info", log.Fields{"DeviceID": id}) |
| return |
| } |
| voltDevice := va.GetDevice(id) |
| if voltDevice != nil { |
| voltDevice.Ports.Range(getPorts) |
| } |
| |
| dhcpSessionInfoJSON, err := json.Marshal(dhcpSessionInfoResp) |
| if err != nil { |
| logger.Errorw(ctx, "Error occurred while marshaling dhcp session info response", log.Fields{"DeviceID": id, "DhcpSessionInfoResp": dhcpSessionInfoResp, "Error": err}) |
| w.WriteHeader(http.StatusInternalServerError) |
| return |
| } |
| |
| w.Header().Add("Content-Type", "application/json") |
| _, err = w.Write(dhcpSessionInfoJSON) |
| if err != nil { |
| logger.Errorw(ctx, "error in sending dhcp session info response", log.Fields{"DeviceID": id, "DhcpSessionInfo": dhcpSessionInfoResp, "Error": err}) |
| w.WriteHeader(http.StatusInternalServerError) |
| return |
| } |
| logger.Debugw(ctx, "Fetching Dhcp Session Info", log.Fields{"DhcpSessionInfo": dhcpSessionInfoResp}) |
| } |