Naveen Sampath | 04696f7 | 2022-06-13 15:19:14 +0530 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2022-present Open Networking Foundation |
| 3 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | * you may not use this file except in compliance with the License. |
| 5 | * You may obtain a copy of the License at |
| 6 | * |
| 7 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | * |
| 9 | * Unless required by applicable law or agreed to in writing, software |
| 10 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | * See the License for the specific language governing permissions and |
| 13 | * limitations under the License. |
| 14 | */ |
| 15 | |
| 16 | package nbi |
| 17 | |
| 18 | import ( |
| 19 | "encoding/json" |
| 20 | "net" |
| 21 | "net/http" |
| 22 | "strconv" |
| 23 | "time" |
| 24 | |
| 25 | "github.com/gorilla/mux" |
| 26 | app "voltha-go-controller/internal/pkg/application" |
Tinoj Joseph | 1d10832 | 2022-07-13 10:07:39 +0530 | [diff] [blame^] | 27 | "voltha-go-controller/log" |
Naveen Sampath | 04696f7 | 2022-06-13 15:19:14 +0530 | [diff] [blame] | 28 | ) |
| 29 | |
| 30 | //DHCPSessionInfoHandle handle dhcp session Requests |
| 31 | type DHCPSessionInfoHandle struct { |
| 32 | } |
| 33 | |
| 34 | // DhcpSessionInfo Information |
| 35 | type DhcpSessionInfo struct { |
| 36 | DeviceID string |
| 37 | Uniport string |
| 38 | Svlan string |
| 39 | Cvlan string |
| 40 | UniVlan string |
| 41 | MacAddress string |
| 42 | IPAddress string |
| 43 | Ipv6Address string |
| 44 | State string |
| 45 | Statev6 string |
| 46 | LeaseTime string |
| 47 | LeaseTimev6 string |
| 48 | } |
| 49 | |
| 50 | // getDhcpSessionFields returns dhcp session information |
| 51 | 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 { |
| 52 | ip := ipAddr.String() |
| 53 | ipv6 := ipv6Addr.String() |
| 54 | relayState := strconv.Itoa(int(rState)) |
| 55 | relayStatev6 := strconv.Itoa(int(rStatev6)) |
| 56 | leaseTime := (lTime.Format(time.RubyDate)) |
| 57 | leasev6Time := (l6Time.Format(time.RubyDate)) |
| 58 | 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} |
| 59 | return dInfo |
| 60 | } |
| 61 | |
| 62 | // validateArgs validate the arguements |
| 63 | func validateArgs(sv string, cv string, macAddr string, svlan string, cvlan string, mac string) bool { |
| 64 | var vlanFlag bool |
| 65 | var macFlag bool |
| 66 | |
| 67 | if ((sv == svlan) || (len(svlan) == 0)) && ((cv == cvlan) || (len(cvlan) == 0)) { |
| 68 | vlanFlag = true |
| 69 | } |
| 70 | |
| 71 | if mac == macAddr || len(mac) == 0 { |
| 72 | macFlag = true |
| 73 | } |
| 74 | |
| 75 | if macFlag && vlanFlag { |
| 76 | return true |
| 77 | } |
| 78 | return false |
| 79 | } |
| 80 | |
| 81 | // serveHTTP for actions performed on API. |
| 82 | func (dh *DHCPSessionInfoHandle) ServeHTTP(w http.ResponseWriter, r *http.Request) { |
| 83 | logger.Infow(ctx, "Received-northbound-request", log.Fields{"Method": r.Method, "URL": r.URL}) |
| 84 | switch r.Method { |
| 85 | case "GET": |
| 86 | dh.getDhcpSessionInfo(w, r) |
| 87 | default: |
| 88 | logger.Warnw(ctx, "Unsupported Method", log.Fields{"Method": r.Method}) |
| 89 | } |
| 90 | } |
| 91 | |
| 92 | // getDhcpSessionInfo to retrieve dhcp session information. |
| 93 | func (dh *DHCPSessionInfoHandle) getDhcpSessionInfo(w http.ResponseWriter, r *http.Request) { |
| 94 | vars := mux.Vars(r) |
| 95 | id := vars["id"] |
| 96 | mac := vars["mac"] |
| 97 | svlan := vars["svlan"] |
| 98 | cvlan := vars["cvlan"] |
| 99 | |
| 100 | var dhcpData *DhcpSessionInfo |
| 101 | |
| 102 | va := app.GetApplication() |
| 103 | dhcpSessionInfoResp := []*DhcpSessionInfo{} |
| 104 | |
| 105 | getPorts := func(key, value interface{}) bool { |
| 106 | port := key.(string) |
| 107 | vp := value.(*app.VoltPort) |
| 108 | |
| 109 | //Ignore if UNI port is not UP |
| 110 | if vp.State != app.PortStateUp { |
| 111 | return true |
| 112 | } |
| 113 | |
| 114 | //Obtain all VPVs associated with the port |
| 115 | vnets, ok := va.VnetsByPort.Load(port) |
| 116 | if !ok { |
| 117 | return true |
| 118 | } |
| 119 | |
| 120 | for _, vpv := range vnets.([]*app.VoltPortVnet) { |
| 121 | // When only device id is provided as arguement |
| 122 | sv := strconv.Itoa(int(vpv.SVlan)) |
| 123 | cv := strconv.Itoa(int(vpv.CVlan)) |
| 124 | uv := strconv.Itoa(int(vpv.UniVlan)) |
| 125 | macAddr := (vpv.MacAddr).String() |
| 126 | |
| 127 | validData := validateArgs(sv, cv, macAddr, svlan, cvlan, mac) |
| 128 | |
| 129 | if validData { |
| 130 | dhcpData = getDhcpSessionFields(id, vpv.Port, sv, cv, uv, macAddr, vpv.Ipv4Addr, vpv.Ipv6Addr, vpv.RelayState, vpv.RelayStatev6, vpv.DhcpExpiryTime, vpv.Dhcp6ExpiryTime) |
| 131 | dhcpSessionInfoResp = append(dhcpSessionInfoResp, dhcpData) |
| 132 | } |
| 133 | } |
| 134 | return true |
| 135 | } |
| 136 | |
| 137 | if len(id) == 0 { |
| 138 | logger.Errorw(ctx, "No Device Id Provided for Dhcp session Info", log.Fields{"DeviceID": id}) |
| 139 | return |
| 140 | } |
| 141 | voltDevice := va.GetDevice(id) |
| 142 | if voltDevice != nil { |
| 143 | voltDevice.Ports.Range(getPorts) |
| 144 | } |
| 145 | |
| 146 | dhcpSessionInfoJSON, err := json.Marshal(dhcpSessionInfoResp) |
| 147 | if err != nil { |
| 148 | logger.Errorw(ctx, "Error occurred while marshaling dhcp session info response", log.Fields{"Error": err}) |
| 149 | w.WriteHeader(http.StatusInternalServerError) |
| 150 | return |
| 151 | } |
| 152 | |
| 153 | w.Header().Add("Content-Type", "application/json") |
| 154 | _, err = w.Write(dhcpSessionInfoJSON) |
| 155 | if err != nil { |
| 156 | logger.Errorw(ctx, "error in sending dhcp session info response", log.Fields{"Error": err}) |
| 157 | w.WriteHeader(http.StatusInternalServerError) |
| 158 | } |
| 159 | |
| 160 | } |