Skip to content

Commit

Permalink
Merge pull request #11 from uni-tue-kn/ARP
Browse files Browse the repository at this point in the history
ARP Reply + UI refactor + Port config
  • Loading branch information
NE4Y authored Mar 11, 2024
2 parents 1c2b0ef + 422cfa1 commit f0a700b
Show file tree
Hide file tree
Showing 85 changed files with 4,959 additions and 1,893 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/docker-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on:
push:
branches: [ "main", "dev"]
pull_request:
branches: [ "main" ]
branches: [ "main", "dev"]

jobs:
build:
Expand Down
15 changes: 14 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,20 @@
- Random Ethernet src addresses are now always unicast
- Detection mechanism that clears local storage if stored streams do not have all required properties
- This may be the case if an update introduces new properties, but the old stored values in local storage dont have them

- Refactor Configuration GUI code
- Switch to utoipa + swagger-ui for REST-API docs
- Add `config.json` file that can be used to specify the traffic generation (front panel) ports
- Add `ARP Reply` option in UI. If enabled, the switch answers all ARP requests that it receives on that port.

### Refactor REST-API endpoint `/api/trafficgen`
- Endpoint `/api/trafficgen` refactored to better reflect encapsulation methods
- Streamsettings are now grouped according to protocol (see `/api/docs` for examples)
- Ethernet related configuration (src & dst mac) are now under `ethernet`
- VLAN & QinQ related configuration are now under `vlan`
- IP related configuration are now under `ip`
- Fields (`vlan`, `mpls_stack`, `vxlan`) are only required if corresponding encapsulation is active
- `number_of_lse` in stream description is now only required if MPLS encapsulation is used

## v2.1.2
- Added RTT visualization
- Cleaner monitoring routine in controller
Expand Down
7 changes: 5 additions & 2 deletions Configuration GUI/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import styled from "styled-components"
import ErrorView from "./components/ErrorView"
import Navbar from "./components/Navbar"

import Home from "./sites/Home"
import Home, {GitHub} from "./sites/Home"
import Setup from "./sites/Setup";
import Ports from "./sites/Ports";
import Settings from "./sites/Settings";
Expand Down Expand Up @@ -74,7 +74,9 @@ const App = () => {
return
}

if(!stored_settings.every(s => Object.keys(defaultStreamSetting).every(key => Object.keys(s).includes(key)))) {
if(!stored_settings.every(s => Object.keys(defaultStreamSetting).every(key => {
return Object.keys(s).includes(key) && s.mpls_stack != undefined
}))) {
alert("Incompatible stream description found. This may be due to an update. Resetting local storage.")
localStorage.clear()
window.location.reload()
Expand Down Expand Up @@ -119,6 +121,7 @@ const App = () => {
<Offline/>
}
</Wrapper>

</Container>
</AxiosInterceptor>
</Col>
Expand Down
19 changes: 18 additions & 1 deletion Configuration GUI/src/assets/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@

:root {
--color-primary: #e74c3c;
--color-primary-light: #ff9e93;
--color-okay: #27ae60;
--color-okay-hover: #20864b;
--color-secondary: #2c3e50;
--color-seconary-light: #415e7a;
--color-secondary-light: #415e7a;
--color-yellow: #f1c40f;
}

Expand Down Expand Up @@ -119,6 +120,22 @@ table tr th {
.btn {
padding: 10px 10px 10px 10px !important;
}

.accordion-button:not(.collapsed) {
background-color: var(--color-secondary);
color: #FFF;
}

.accordion-button {
background-color: var(--color-secondary);
color: #FFF;
}

.accordion-button::after {
-webkit-filter: grayscale(1) invert(1);
filter: grayscale(1) invert(1);
}

@media only screen and (max-width: 450px) {
.sidebar-nav .nav-link i {
font-size: 20px;
Expand Down
43 changes: 43 additions & 0 deletions Configuration GUI/src/common/Definitions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/* Copyright 2022-present University of Tuebingen, Chair of Communication Networks
*
* 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.
*/

/*
* Steffen Lindner (steffen.lindner@uni-tuebingen.de)
*/

export const fec_mapping: { [name: string]: string } = {
"BF_FEC_TYP_NONE": "None",
"BF_FEC_TYP_FC": "Firecode",
"BF_FEC_TYP_REED_SOLOMON": "Reed Solomon"
}
export const auto_neg_mapping: { [name: string]: string } = {
"PM_AN_DEFAULT": "Auto",
"PM_AN_FORCE_DISABLE": "Off",
"PM_AN_FORCE_ENABLE": "On"
}

export const speed_mapping: { [name: string]: string } = {
"BF_SPEED_1G": "1G",
"BF_SPEED_10G": "10G",
"BF_SPEED_25G": "25G",
"BF_SPEED_40G": "40G",
"BF_SPEED_50G": "50G",
"BF_SPEED_100G": "100G"
}

export const loopback_mapping: { [name: string]: string } = {
"BF_LPBK_NONE": "Off",
"BF_LPBK_MAC_NEAR": "On"
}
74 changes: 47 additions & 27 deletions Configuration GUI/src/common/Interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,19 +86,25 @@ export interface StreamSettings {
mpls_stack: MPLSHeader[],
port: number,
stream_id: number,
vlan_id: number,
pcp: number,
dei: number,
inner_vlan_id: number,
inner_pcp: number,
inner_dei: number,
eth_src: string,
eth_dst: string,
ip_src: string,
ip_dst: string,
ip_tos: number,
ip_src_mask: string,
ip_dst_mask: string,
vlan: {
vlan_id: number,
pcp: number,
dei: number,
inner_vlan_id: number,
inner_pcp: number,
inner_dei: number,
}
ethernet: {
eth_src: string,
eth_dst: string,
},
ip: {
ip_src: string,
ip_dst: string,
ip_tos: number,
ip_src_mask: string,
ip_dst_mask: string,
}
active: boolean
vxlan: {
eth_src: string,
Expand Down Expand Up @@ -164,20 +170,26 @@ export const DefaultStreamSettings = (id: number, port: number) => {
let stream: StreamSettings = {
port: port,
stream_id: id,
vlan_id: 1,
pcp: 0,
dei: 0,
inner_vlan_id: 1,
inner_pcp: 0,
inner_dei: 0,
vlan: {
vlan_id: 1,
pcp: 0,
dei: 0,
inner_vlan_id: 1,
inner_pcp: 0,
inner_dei: 0
},
mpls_stack: [],
eth_src: "32:D5:42:2A:F6:92",
eth_dst: "81:E7:9D:E3:AD:47",
ip_src: "192.168.178.10",
ip_dst: "192.168.178.11",
ip_tos: 0,
ip_src_mask: "0.0.0.0",
ip_dst_mask: "0.0.0.0",
ethernet: {
eth_src: "32:D5:42:2A:F6:92",
eth_dst: "81:E7:9D:E3:AD:47"
},
ip: {
ip_src: "192.168.178.10",
ip_dst: "192.168.178.11",
ip_tos: 0,
ip_src_mask: "0.0.0.0",
ip_dst_mask: "0.0.0.0"
},
active: false,
vxlan: {
eth_src: "32:D5:42:2A:F6:92",
Expand All @@ -191,4 +203,12 @@ export const DefaultStreamSettings = (id: number, port: number) => {
}

return stream
}
}

export interface P4TGConfig {
tg_ports: {
port: number,
mac: string,
arp_reply: boolean
}[]
}
52 changes: 52 additions & 0 deletions Configuration GUI/src/common/Validators.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/* Copyright 2022-present University of Tuebingen, Chair of Communication Networks
*
* 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.
*/

/*
* Steffen Lindner (steffen.lindner@uni-tuebingen.de)
*/

import {MPLSHeader} from "./Interfaces";

export const validateMAC = (mac: string) => {
let regex = /^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/;

return regex.test(mac)
}

export const validateIP = (ip: string) => {
let regex = /^(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}$/gm;

return regex.test(ip)
}

export const validateMPLS = (mpls_stack: MPLSHeader[]) => {
let result = true;
mpls_stack.forEach((lse: MPLSHeader) => {
result = result && lse.label >= 0 && lse.label < 1048575 && lse.tc >= 0 && lse.tc < 8 && lse.ttl >= 0 && lse.ttl < 256;
});
return result;
}

export const validateToS = (tos: number) => {
return !isNaN(tos) && (0 <= tos) && tos <= (2 ** 7 - 1)
}

export const validateUdpPort = (port: number) => {
return !isNaN(port) && (0 <= port) && port <= (2 ** 16 - 1)
}

export const validateVNI = (vni: number) => {
return !isNaN(vni) && (0 <= vni) && vni <= (2 ** 24 - 1)
}
9 changes: 2 additions & 7 deletions Configuration GUI/src/components/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ import {Row} from 'react-bootstrap'

import P4TGLogo from "../assets/p4tg_logo_white.png"
import config from "../config";

const StyledLink = styled(Link) <{ active?: boolean }>`
styled(Link) <{ active?: boolean }>`
text-decoration: none;
margin-right: 15px;
color: var(--cui-nav-link-color);
Expand All @@ -37,8 +36,7 @@ const StyledLink = styled(Link) <{ active?: boolean }>`
:hover {
background: #5c636a;
}
`

`;
const StyledImg = styled.img`
width: 80px;
`
Expand Down Expand Up @@ -102,14 +100,11 @@ const Navbar = () => {
<NavLink to={"/ports"} text={""} icon={"bi bi-ethernet"}/>
<NavLink to={"/tables"} text={""} icon={"bi bi-table"}/>
<NavLink to={"/settings"} text={""} icon={"bi bi-gear-wide-connected"}/>
{/*<NavLink to={config.API_URL + "/docs"} text={""} icon={"bi bi-file-earmark-text"}/>*/}
<Row className="flex-grow-1">
</Row>
<Row>
<CNavItem className="flex-grow-1 mb-2">
<span>v2.2.0</span>
{/*<a href={"#"} role="button" onClick={() => setup()} className={"nav-link logout"}>*/}
{/* <i className="bi bi-box-arrow-left me-2"></i></a>*/}
</CNavItem>
</Row>
</CSidebarNav>
Expand Down
2 changes: 1 addition & 1 deletion Configuration GUI/src/components/SendReceiveMonitor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*/

import React from 'react'
import {Col, Row} from "react-bootstrap";
import {Col} from "react-bootstrap";
import styled from "styled-components";
import {Statistics} from "../common/Interfaces";
import Status from "../components/Status";
Expand Down
16 changes: 2 additions & 14 deletions Configuration GUI/src/components/StatView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -280,10 +280,6 @@ const StatView = ({ stats, time_stats, port_mapping, mode, visual }: { stats: St
const rx_rate_l1 = addRates(stats.rx_rate_l1, Object.values(port_mapping).map(Number))
const rx_rate_l2 = addRates(stats.rx_rate_l2, Object.values(port_mapping).map(Number))

const mean_frame_size_tx = (tx_rate_l1 - tx_rate_l2) <= 0 ? 0 : 20 * tx_rate_l2 / (tx_rate_l1 - tx_rate_l2)
//const mean_iat_tx = tx_rate_l1 > 0 ? (mean_frame_size_tx+20) * 8 / (tx_rate_l1 * 10**-9) : 0
const mean_iat_rx = rx_rate_l1 > 0 ? (mean_frame_size_tx + 20) * 8 / (rx_rate_l1 * 10 ** -9) : 0


return <>
{ visual ?
Expand Down Expand Up @@ -417,10 +413,6 @@ const StatView = ({ stats, time_stats, port_mapping, mode, visual }: { stats: St
<td>{formatNanoSeconds(rtt.max)}</td>
<td>{formatNanoSeconds(rtt.jitter)}</td>
<td>{rtt.n}</td>
{/*<td>{formatNanoSeconds(stats.min_rtt)}</td>*/}
{/*<td>{formatNanoSeconds(stats.rtt)}</td>*/}
{/*<td>{formatNanoSeconds(stats.max_rtt)}</td>*/}
{/*<td>{formatNanoSeconds(stats.jitter)}</td>*/}
</tr>
</tbody>
</Table>
Expand All @@ -437,7 +429,7 @@ const StatView = ({ stats, time_stats, port_mapping, mode, visual }: { stats: St
</tr>
</thead>
<tbody>
{["Multicast", "Broadcast", "Unicast", "VxLAN", "Non-Unicast", "Total"].map((v, i) => {
{["Multicast", "Broadcast", "Unicast", "VxLAN", "Non-Unicast", " ", "Total"].map((v, i) => {
let key = v.toLowerCase()
let data = get_frame_types(key)

Expand Down Expand Up @@ -472,8 +464,6 @@ const StatView = ({ stats, time_stats, port_mapping, mode, visual }: { stats: St
<td>{v != " " ? v : "\u00A0" }</td> {/* Quick hack for empty row */}
<td>{v != " " ? formatFrameCount(data.tx) : null}</td>
<td>{v != " " ? formatFrameCount(data.rx) : null}</td>
{/*<td>{stats.frame_type_data.tx[key]}</td>*/}
{/*<td>{stats.frame_type_data.rx[key]}</td>*/}
</tr>
})
}
Expand All @@ -490,16 +480,14 @@ const StatView = ({ stats, time_stats, port_mapping, mode, visual }: { stats: St
</tr>
</thead>
<tbody>
{["VLAN", "QinQ", "IPv4", "IPv6", "MPLS", "Unknown"].map((v, i) => {
{["VLAN", "QinQ", "IPv4", "IPv6", "MPLS", "ARP", "Unknown"].map((v, i) => {
let key = v.toLowerCase()
let data = get_frame_types(key)

return <tr>
<td>{v}</td>
<td>{formatFrameCount(data.tx)}</td>
<td>{formatFrameCount(data.rx)}</td>
{/*<td>{stats.frame_type_data.tx[key]}</td>*/}
{/*<td>{stats.frame_type_data.rx[key]}</td>*/}
</tr>
})
}
Expand Down
Loading

0 comments on commit f0a700b

Please sign in to comment.