blob: eba1a1d5b8e46f1eaf3af2f806ab4fd0c38e0bae [file] [log] [blame]
/*
* 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})
}