diff --git a/ZodiacFX/src/command.c b/ZodiacFX/src/command.c index 8c1befa..9e1ae0a 100644 --- a/ZodiacFX/src/command.c +++ b/ZodiacFX/src/command.c @@ -457,6 +457,36 @@ void command_root(char *command, char *param1, char *param2, char *param3) return; } + // Build shortcut - c to show config is saved + if (strcmp(command, "c")==0) + { + printf("\r\n"); + printf("Build Configuration Check\r\n"); + printf("-------------------------\r\n"); + printf(" Name: %s\r\n",Zodiac_Config.device_name); + printf(" MAC Address: %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\r\n",Zodiac_Config.MAC_address[0], Zodiac_Config.MAC_address[1], Zodiac_Config.MAC_address[2], Zodiac_Config.MAC_address[3], Zodiac_Config.MAC_address[4], Zodiac_Config.MAC_address[5]); + printf(" IP Address: %d.%d.%d.%d\r\n" , Zodiac_Config.IP_address[0], Zodiac_Config.IP_address[1], Zodiac_Config.IP_address[2], Zodiac_Config.IP_address[3]); + printf(" Netmask: %d.%d.%d.%d\r\n" , Zodiac_Config.netmask[0], Zodiac_Config.netmask[1], Zodiac_Config.netmask[2], Zodiac_Config.netmask[3]); + printf(" Gateway: %d.%d.%d.%d\r\n" , Zodiac_Config.gateway_address[0], Zodiac_Config.gateway_address[1], Zodiac_Config.gateway_address[2], Zodiac_Config.gateway_address[3]); + printf(" OpenFlow Controller: %d.%d.%d.%d\r\n" , Zodiac_Config.OFIP_address[0], Zodiac_Config.OFIP_address[1], Zodiac_Config.OFIP_address[2], Zodiac_Config.OFIP_address[3]); + printf(" OpenFlow Port: %d\r\n" , Zodiac_Config.OFPort); + if (Zodiac_Config.OFEnabled == OF_ENABLED) printf(" Openflow Status: Enabled\r\n"); + if (Zodiac_Config.OFEnabled == OF_DISABLED) printf(" Openflow Status: Disabled\r\n"); + if (Zodiac_Config.failstate == 0) printf(" Failstate: Secure\r\n"); + if (Zodiac_Config.failstate == 1) printf(" Failstate: Safe\r\n"); + if (Zodiac_Config.of_version == 1) { + printf(" Force OpenFlow version: 1.0 (0x01)\r\n"); + } else if (Zodiac_Config.of_version == 4){ + printf(" Force OpenFlow version: 1.3 (0x04)\r\n"); + } else { + printf(" Force OpenFlow version: Disabled\r\n"); + } + if (Zodiac_Config.ethtype_filter == 1) printf(" EtherType Filtering: Enabled\r\n"); + if (Zodiac_Config.ethtype_filter != 1) printf(" EtherType Filtering: Disabled\r\n"); + printf("\r\n\n"); + return; + } + // Restart switch if (strcmp(command, "restart")==0) { @@ -1101,9 +1131,16 @@ void command_openflow(char *command, char *param1, char *param2, char *param3) case OFPXMT_OFB_ETH_TYPE: memcpy(&oxm_value16, ofp13_oxm_match[i] + sizeof(struct oxm_header13) + match_size, 2); if (ntohs(oxm_value16) == 0x0806)printf(" ETH Type: ARP\r\n"); - if (ntohs(oxm_value16) == 0x0800)printf(" ETH Type: IPv4\r\n"); - if (ntohs(oxm_value16) == 0x86dd)printf(" ETH Type: IPv6\r\n"); - if (ntohs(oxm_value16) == 0x8100)printf(" ETH Type: VLAN\r\n"); + else if (ntohs(oxm_value16) == 0x0800)printf(" ETH Type: IPv4\r\n"); + else if (ntohs(oxm_value16) == 0x86dd)printf(" ETH Type: IPv6\r\n"); + else if (ntohs(oxm_value16) == 0x8100)printf(" ETH Type: VLAN\r\n"); + else if (ntohs(oxm_value16) == 0x888e)printf(" ETH Type: EAPOL\r\n"); + else if (ntohs(oxm_value16) == 0x88cc)printf(" ETH Type: LLDP\r\n"); + else if (ntohs(oxm_value16) == 0x8999)printf(" ETH Type: BDDP\r\n"); + else if (ntohs(oxm_value16) == 0x9100)printf(" ETH Type: VLAN(D)\r\n"); + else if (ntohs(oxm_value16) == 0x8847)printf(" ETH Type: MPLS (Unicast)\r\n"); + else if (ntohs(oxm_value16) == 0x8848)printf(" ETH Type: MPLS (Multicast)\r\n"); + else printf(" ETH Type: 0x%X\r\n",ntohs(oxm_value16)); break; case OFPXMT_OFB_IP_PROTO: @@ -1170,6 +1207,61 @@ void command_openflow(char *command, char *param1, char *param2, char *param3) if (oxm_value16 != 0) printf(" VLAN ID: %d\r\n",(ntohs(oxm_value16) - OFPVID_PRESENT)); break; + case OFPXMT_OFB_MPLS_LABEL: + memcpy(&oxm_value32, ofp13_oxm_match[i] + sizeof(struct oxm_header13) + match_size, 4); + if (oxm_value32 != 0) printf(" MPLS Label: %d\r\n",(ntohl(oxm_value32))); + break; + + case OFPXMT_OFB_MPLS_TC: + memcpy(&oxm_value8, ofp13_oxm_match[i] + sizeof(struct oxm_header13) + match_size, 1); + if (oxm_value8 != 0) printf(" MPLS TC: %d\r\n",(oxm_value8)); + break; + + case OFPXMT_OFB_MPLS_BOS: + memcpy(&oxm_value8, ofp13_oxm_match[i] + sizeof(struct oxm_header13) + match_size, 1); + if (oxm_value8 != 0) printf(" MPLS BoS: %d\r\n",(oxm_value8)); + break; + + case OFPXMT_OFB_ARP_OP: + memcpy(&oxm_value16, ofp13_oxm_match[i] + sizeof(struct oxm_header13) + match_size, 2); + if (oxm_value16 == 1) printf(" ARP OP Code: Request (%d)\r\n",ntohs(oxm_value16)); + if (oxm_value16 == 2) printf(" ARP OP Code: Reply (%d)\r\n",ntohs(oxm_value16)); + break; + + case OFPXMT_OFB_ARP_SPA: + if (has_mask) + { + memcpy(&oxm_ipv4, ofp13_oxm_match[i] + sizeof(struct oxm_header13) + match_size, 8); + printf(" Source IP: %d.%d.%d.%d / %d.%d.%d.%d\r\n", oxm_ipv4[0], oxm_ipv4[1], oxm_ipv4[2], oxm_ipv4[3], oxm_ipv4[4], oxm_ipv4[5], oxm_ipv4[6], oxm_ipv4[7]); + } else { + memcpy(&oxm_ipv4, ofp13_oxm_match[i] + sizeof(struct oxm_header13) + match_size, 4); + printf(" Source IP: %d.%d.%d.%d\r\n", oxm_ipv4[0], oxm_ipv4[1], oxm_ipv4[2], oxm_ipv4[3]); + } + break; + + case OFPXMT_OFB_ARP_TPA: + if (has_mask) + { + memcpy(&oxm_ipv4, ofp13_oxm_match[i] + sizeof(struct oxm_header13) + match_size, 8); + printf(" Target IP: %d.%d.%d.%d / %d.%d.%d.%d\r\n", oxm_ipv4[0], oxm_ipv4[1], oxm_ipv4[2], oxm_ipv4[3], oxm_ipv4[4], oxm_ipv4[5], oxm_ipv4[6], oxm_ipv4[7]); + } else { + memcpy(&oxm_ipv4, ofp13_oxm_match[i] + sizeof(struct oxm_header13) + match_size, 4); + printf(" Target IP: %d.%d.%d.%d\r\n", oxm_ipv4[0], oxm_ipv4[1], oxm_ipv4[2], oxm_ipv4[3]); + } + break; + + case OFPXMT_OFB_ARP_SHA: + memcpy(&oxm_eth, ofp13_oxm_match[i] + sizeof(struct oxm_header13) + match_size, 6); + printf(" Source MAC: %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\r\n", oxm_eth[0], oxm_eth[1], oxm_eth[2], oxm_eth[3], oxm_eth[4], oxm_eth[5]); + break; + + case OFPXMT_OFB_ARP_THA: + memcpy(&oxm_eth, ofp13_oxm_match[i] + sizeof(struct oxm_header13) + match_size, 6); + printf(" Target MAC: %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\r\n", oxm_eth[0], oxm_eth[1], oxm_eth[2], oxm_eth[3], oxm_eth[4], oxm_eth[5]); + break; + + + }; match_size += (oxm_header.oxm_len + sizeof(struct oxm_header13)); } @@ -1263,9 +1355,16 @@ void command_openflow(char *command, char *param1, char *param2, char *param3) case OFPXMT_OFB_ETH_TYPE: memcpy(&oxm_value16, act_set_field->field + sizeof(struct oxm_header13), 2); if (ntohs(oxm_value16) == 0x0806 )printf(" Set ETH Type: ARP\r\n"); - if (ntohs(oxm_value16) == 0x0800 )printf(" Set ETH Type: IPv4\r\n"); - if (ntohs(oxm_value16) == 0x86dd )printf(" Set ETH Type: IPv6\r\n"); - if (ntohs(oxm_value16) == 0x8100 )printf(" Set ETH Type: VLAN\r\n"); + else if (ntohs(oxm_value16) == 0x0800)printf(" Set ETH Type: IPv4\r\n"); + else if (ntohs(oxm_value16) == 0x86dd)printf(" Set ETH Type: IPv6\r\n"); + else if (ntohs(oxm_value16) == 0x8100)printf(" Set ETH Type: VLAN\r\n"); + else if (ntohs(oxm_value16) == 0x888e)printf(" Set ETH Type: EAPOL\r\n"); + else if (ntohs(oxm_value16) == 0x88cc)printf(" Set ETH Type: LLDP\r\n"); + else if (ntohs(oxm_value16) == 0x8999)printf(" Set ETH Type: BDDP\r\n"); + else if (ntohs(oxm_value16) == 0x9100)printf(" Set ETH Type: VLAN(D)\r\n"); + else if (ntohs(oxm_value16) == 0x8847)printf(" Set ETH Type: MPLS (Unicast)\r\n"); + else if (ntohs(oxm_value16) == 0x8848)printf(" Set ETH Type: MPLS (Multicast)\r\n"); + else printf(" Set ETH Type: VLAN\r\n",ntohs(oxm_value16)); break; case OFPXMT_OFB_IPV4_SRC: @@ -1339,6 +1438,21 @@ void command_openflow(char *command, char *param1, char *param2, char *param3) memcpy(&oxm_eth, act_set_field->field + sizeof(struct oxm_header13), 6); printf(" Set ARP Target HA: %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\r\n", oxm_eth[0], oxm_eth[1], oxm_eth[2], oxm_eth[3], oxm_eth[4], oxm_eth[5]); break; + + case OFPXMT_OFB_MPLS_LABEL: + memcpy(&oxm_value32, act_set_field->field + sizeof(struct oxm_header13), 4); + printf(" Set MPLS Label: %d\r\n",ntohl(oxm_value32)); + break; + + case OFPXMT_OFB_MPLS_TC: + memcpy(&oxm_value8, act_set_field->field + sizeof(struct oxm_header13), 1); + printf(" Set MPLS TC: %d\r\n",ntohs(oxm_value8)); + break; + + case OFPXMT_OFB_MPLS_BOS: + memcpy(&oxm_value8, act_set_field->field + sizeof(struct oxm_header13), 1); + printf(" Set MPLS BoS: %d\r\n",ntohs(oxm_value8)); + break; }; } @@ -1353,6 +1467,17 @@ void command_openflow(char *command, char *param1, char *param2, char *param3) { printf(" Pop VLAN tag\r\n"); } + + if (htons(act_hdr->type) == OFPAT13_PUSH_MPLS) + { + struct ofp13_action_push *act_push = act_hdr; + printf(" Push MPLS tag\r\n"); + } + + if (htons(act_hdr->type) == OFPAT13_POP_MPLS) + { + printf(" Pop MPLS tag\r\n"); + } act_size += htons(act_hdr->len); } diff --git a/ZodiacFX/src/config/config_zodiac.h b/ZodiacFX/src/config/config_zodiac.h index d24b34d..543f272 100644 --- a/ZodiacFX/src/config/config_zodiac.h +++ b/ZodiacFX/src/config/config_zodiac.h @@ -31,7 +31,7 @@ #define CONFIG_ZODIAC_H_ -#define VERSION "0.82" // Firmware version number +#define VERSION "0.83" // Firmware version number #define TOTAL_PORTS 4 // Total number of physical ports on the Zodiac FX diff --git a/ZodiacFX/src/http.c b/ZodiacFX/src/http.c index 9846d63..cb24118 100644 --- a/ZodiacFX/src/http.c +++ b/ZodiacFX/src/http.c @@ -2150,7 +2150,7 @@ static uint8_t interfaceCreate_Upload(void) "

Firmware Update

"\ "

"\ ""\ - "

Browser firmware update supports official binaries (version 0.80 and later).

Please find the latest version in the forums.

"\ + "

Browser firmware update supports official binaries (version 0.81 and later).

Please find the latest version in the forums.

"\ "
"\ "

"\ ""\ @@ -3078,9 +3078,16 @@ if (iLastFlow > 0) case OFPXMT_OFB_ETH_TYPE: memcpy(&oxm_value16, ofp13_oxm_match[i] + sizeof(struct oxm_header13) + match_size, 2); if (ntohs(oxm_value16) == 0x0806)snprintf(shared_buffer+strlen(shared_buffer), SHARED_BUFFER_LEN-strlen(shared_buffer)," ETH Type: ARP\r\n"); - if (ntohs(oxm_value16) == 0x0800)snprintf(shared_buffer+strlen(shared_buffer), SHARED_BUFFER_LEN-strlen(shared_buffer)," ETH Type: IPv4\r\n"); - if (ntohs(oxm_value16) == 0x86dd)snprintf(shared_buffer+strlen(shared_buffer), SHARED_BUFFER_LEN-strlen(shared_buffer)," ETH Type: IPv6\r\n"); - if (ntohs(oxm_value16) == 0x8100)snprintf(shared_buffer+strlen(shared_buffer), SHARED_BUFFER_LEN-strlen(shared_buffer)," ETH Type: VLAN\r\n"); + else if (ntohs(oxm_value16) == 0x0800)snprintf(shared_buffer+strlen(shared_buffer), SHARED_BUFFER_LEN-strlen(shared_buffer)," ETH Type: IPv4\r\n"); + else if (ntohs(oxm_value16) == 0x86dd)snprintf(shared_buffer+strlen(shared_buffer), SHARED_BUFFER_LEN-strlen(shared_buffer)," ETH Type: IPv6\r\n"); + else if (ntohs(oxm_value16) == 0x8100)snprintf(shared_buffer+strlen(shared_buffer), SHARED_BUFFER_LEN-strlen(shared_buffer)," ETH Type: VLAN\r\n"); + else if (ntohs(oxm_value16) == 0x9100)snprintf(shared_buffer+strlen(shared_buffer), SHARED_BUFFER_LEN-strlen(shared_buffer)," ETH Type: VLAN(D)\r\n"); + else if (ntohs(oxm_value16) == 0x888e)snprintf(shared_buffer+strlen(shared_buffer), SHARED_BUFFER_LEN-strlen(shared_buffer)," ETH Type: EAPOL\r\n"); + else if (ntohs(oxm_value16) == 0x88cc)snprintf(shared_buffer+strlen(shared_buffer), SHARED_BUFFER_LEN-strlen(shared_buffer)," ETH Type: LLDP\r\n"); + else if (ntohs(oxm_value16) == 0x8999)snprintf(shared_buffer+strlen(shared_buffer), SHARED_BUFFER_LEN-strlen(shared_buffer)," ETH Type: BDDP\r\n"); + else if (ntohs(oxm_value16) == 0x8847)snprintf(shared_buffer+strlen(shared_buffer), SHARED_BUFFER_LEN-strlen(shared_buffer)," ETH Type: MPLS (Unicast)\r\n"); + else if (ntohs(oxm_value16) == 0x8848)snprintf(shared_buffer+strlen(shared_buffer), SHARED_BUFFER_LEN-strlen(shared_buffer)," ETH Type: MPLS (Multicast)\r\n"); + else snprintf(shared_buffer+strlen(shared_buffer), SHARED_BUFFER_LEN-strlen(shared_buffer)," ETH Type: 0x%X\r\n", ntohs(oxm_value16)); break; case OFPXMT_OFB_IP_PROTO: @@ -3146,6 +3153,21 @@ if (iLastFlow > 0) memcpy(&oxm_value16, ofp13_oxm_match[i] + sizeof(struct oxm_header13) + match_size, 2); if (oxm_value16 != 0) snprintf(shared_buffer+strlen(shared_buffer), SHARED_BUFFER_LEN-strlen(shared_buffer)," VLAN ID: %d\r\n",(ntohs(oxm_value16) - OFPVID_PRESENT)); break; + + case OFPXMT_OFB_MPLS_LABEL: + memcpy(&oxm_value32, ofp13_oxm_match[i] + sizeof(struct oxm_header13) + match_size, 4); + if (oxm_value32 != 0) snprintf(shared_buffer+strlen(shared_buffer), SHARED_BUFFER_LEN-strlen(shared_buffer)," MPLS Label: %d\r\n",(ntohl(oxm_value32))); + break; + + case OFPXMT_OFB_MPLS_TC: + memcpy(&oxm_value8, ofp13_oxm_match[i] + sizeof(struct oxm_header13) + match_size, 1); + if (oxm_value8 != 0) snprintf(shared_buffer+strlen(shared_buffer), SHARED_BUFFER_LEN-strlen(shared_buffer)," MPLS TC: %d\r\n",(oxm_value8)); + break; + + case OFPXMT_OFB_MPLS_BOS: + memcpy(&oxm_value8, ofp13_oxm_match[i] + sizeof(struct oxm_header13) + match_size, 1); + if (oxm_value8 != 0) snprintf(shared_buffer+strlen(shared_buffer), SHARED_BUFFER_LEN-strlen(shared_buffer)," MPLS BoS: %d\r\n",(oxm_value8)); + break; }; match_size += (oxm_header.oxm_len + sizeof(struct oxm_header13)); @@ -3317,6 +3339,20 @@ if (iLastFlow > 0) snprintf(shared_buffer+strlen(shared_buffer), SHARED_BUFFER_LEN-strlen(shared_buffer)," Set ARP Target HA: %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\r\n", oxm_eth[0], oxm_eth[1], oxm_eth[2], oxm_eth[3], oxm_eth[4], oxm_eth[5]); break; + case OFPXMT_OFB_MPLS_LABEL: + memcpy(&oxm_value32, act_set_field->field + sizeof(struct oxm_header13), 4); + snprintf(shared_buffer+strlen(shared_buffer), SHARED_BUFFER_LEN-strlen(shared_buffer)," Set MPLS Label: %d\r\n", ntohl(oxm_value32)); + + break; + case OFPXMT_OFB_MPLS_TC: + memcpy(&oxm_value8, act_set_field->field + sizeof(struct oxm_header13), 1); + snprintf(shared_buffer+strlen(shared_buffer), SHARED_BUFFER_LEN-strlen(shared_buffer)," Set MPLS TC: %d\r\n", oxm_value8); + break; + + case OFPXMT_OFB_MPLS_BOS: + memcpy(&oxm_value8, act_set_field->field + sizeof(struct oxm_header13), 1); + snprintf(shared_buffer+strlen(shared_buffer), SHARED_BUFFER_LEN-strlen(shared_buffer)," Set MPLS BoS: %d\r\n", oxm_value8); + break; }; } @@ -3331,6 +3367,17 @@ if (iLastFlow > 0) snprintf(shared_buffer+strlen(shared_buffer), SHARED_BUFFER_LEN-strlen(shared_buffer)," Pop VLAN tag\r\n"); } + if (htons(act_hdr->type) == OFPAT13_PUSH_MPLS) + { + struct ofp13_action_push *act_push = act_hdr; + snprintf(shared_buffer+strlen(shared_buffer), SHARED_BUFFER_LEN-strlen(shared_buffer)," Push MPLS tag\r\n"); + } + + if (htons(act_hdr->type) == OFPAT13_POP_MPLS) + { + snprintf(shared_buffer+strlen(shared_buffer), SHARED_BUFFER_LEN-strlen(shared_buffer)," Pop MPLS tag\r\n"); + } + act_size += htons(act_hdr->len); } } diff --git a/ZodiacFX/src/openflow/of_helper.c b/ZodiacFX/src/openflow/of_helper.c index 3ac3f4c..df1bb5d 100644 --- a/ZodiacFX/src/openflow/of_helper.c +++ b/ZodiacFX/src/openflow/of_helper.c @@ -103,6 +103,7 @@ void set_ip_checksum(uint8_t *p_uc_data, int packet_size, int iphdr_offset) (ip_addr_t*)&(iphdr->dest), IP_PROTO_TCP, packet_size - payload_offset); + TRACE("of_helper.c: TCP header modified, recalculating Checksum. 0x%X", htons(tcphdr->chksum)); } if (IPH_PROTO(iphdr) == IP_PROTO_UDP) { udphdr = (struct udp_hdr*)(p_uc_data + payload_offset); @@ -112,11 +113,13 @@ void set_ip_checksum(uint8_t *p_uc_data, int packet_size, int iphdr_offset) (ip_addr_t*)&(iphdr->dest), IP_PROTO_UDP, packet_size - payload_offset); + TRACE("of_helper.c: UDP header modified, recalculating Checksum. 0x%X", htons(udphdr->chksum)); } if (IPH_PROTO(iphdr) == IP_PROTO_ICMP) { icmphdr = (struct icmp_echo_hdr*)(p_uc_data + payload_offset); icmphdr->chksum = 0; icmphdr->chksum = inet_chksum(icmphdr, packet_size - payload_offset); + TRACE("of_helper.c: ICMP header modified, recalculating Checksum. 0x%X", htons(icmphdr->chksum)); } pbuf_free(p); @@ -271,19 +274,34 @@ int flowmatch10(uint8_t *pBuffer, int port, struct packet_fields *fields) * */ void packet_fields_parser(uint8_t *pBuffer, struct packet_fields *fields) { + // VLAN EtherTypes static const uint8_t vlan1[2] = { 0x81, 0x00 }; static const uint8_t vlan2[2] = { 0x88, 0xa8 }; static const uint8_t vlan3[2] = { 0x91, 0x00 }; static const uint8_t vlan4[2] = { 0x92, 0x00 }; static const uint8_t vlan5[2] = { 0x93, 0x00 }; + // MPLS EtherTypes + static const uint8_t mpls1[2] = { 0x88, 0x47 }; + static const uint8_t mpls2[2] = { 0x88, 0x48 }; fields->isVlanTag = false; + fields->isMPLSTag = false; uint8_t *eth_type = pBuffer + 12; - while(memcmp(eth_type, vlan1, 2)==0 - || memcmp(eth_type, vlan2, 2)==0 - || memcmp(eth_type, vlan3, 2)==0 - || memcmp(eth_type, vlan4, 2)==0 - || memcmp(eth_type, vlan5, 2)==0){ + + // Get MPLS values + if (memcmp(eth_type, mpls1, 2)==0 || memcmp(eth_type, mpls2, 2)==0) + { + uint32_t mpls; + memcpy(&mpls, eth_type+2, 4); + fields->mpls_label = ntohl(mpls)>>12; + fields->mpls_tc = (ntohl(mpls)>>9)&7; + fields->mpls_bos = (ntohl(mpls)>>8)&1; + fields->isMPLSTag = true; + eth_type += 4; + } + // Get VLAN IDs + while(memcmp(eth_type, vlan1, 2)==0 || memcmp(eth_type, vlan2, 2)==0 || memcmp(eth_type, vlan3, 2)==0 || memcmp(eth_type, vlan4, 2)==0 || memcmp(eth_type, vlan5, 2)==0) + { if(fields->isVlanTag == false){ // save outermost value uint8_t tci[2] = { eth_type[2]&0x0f, eth_type[3] }; memcpy(&fields->vlanid, tci, 2); @@ -291,6 +309,7 @@ void packet_fields_parser(uint8_t *pBuffer, struct packet_fields *fields) { fields->isVlanTag = true; eth_type += 4; } + memcpy(&fields->eth_prot, eth_type, 2); fields->payload = eth_type + 2; // payload points to ip_hdr, etc. @@ -336,12 +355,12 @@ int flowmatch13(uint8_t *pBuffer, int port, uint8_t table_id, struct packet_fiel } TRACE("of_helper.c: Looking for match in table %d from port %d : " - "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X -> %.2X:%.2X:%.2X:%.2X:%.2X:%.2X eth type %4.4X", + "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X -> %.2X:%.2X:%.2X:%.2X:%.2X:%.2X - eth type %4.4X - VLAN ID %d", table_id, port, eth_src[0], eth_src[1], eth_src[2], eth_src[3], eth_src[4], eth_src[5], eth_dst[0], eth_dst[1], eth_dst[2], eth_dst[3], eth_dst[4], eth_dst[5], - ntohs(fields->eth_prot)) - + ntohs(fields->eth_prot), ntohs(fields->vlanid)) + for (int i=0;ieth_prot != *(uint16_t*)oxm_value) { - priority_match = -1; + if(*(uint16_t*)oxm_value != htons(0x8847) && *(uint16_t*)oxm_value != htons(0x8848)) + { + priority_match = -1; + } else { + if (!fields->isMPLSTag) + { + priority_match = -1; + } + } } break; @@ -543,6 +570,32 @@ int flowmatch13(uint8_t *pBuffer, int port, uint8_t table_id, struct packet_fiel priority_match = -1; } break; + if (!(fields->isVlanTag && (pBuffer[14]>>5) == oxm_value[0])) + { + priority_match = -1; + } + + case OXM_OF_MPLS_LABEL: + if (fields->isMPLSTag && fields->mpls_label != ntohl(*(uint32_t*)oxm_value)) + { + priority_match = -1; + } + break; + + case OXM_OF_MPLS_TC: + if (fields->isMPLSTag && fields->mpls_tc != *oxm_value) + { + priority_match = -1; + } + break; + + case OXM_OF_MPLS_BOS: + if (fields->isMPLSTag && fields->mpls_bos != *oxm_value) + { + priority_match = -1; + } + break; + } if (priority_match == -1) diff --git a/ZodiacFX/src/openflow/of_helper.h b/ZodiacFX/src/openflow/of_helper.h index 0757a71..9dea30a 100644 --- a/ZodiacFX/src/openflow/of_helper.h +++ b/ZodiacFX/src/openflow/of_helper.h @@ -37,12 +37,17 @@ struct packet_fields { bool parsed; bool isVlanTag; + bool isMPLSTag; uint8_t *payload; uint16_t eth_prot; uint8_t ip_prot; uint16_t vlanid; uint32_t ip_src; uint32_t ip_dst; + uint32_t mpls_label; + uint8_t mpls_tc; + uint8_t mpls_bos; + uint8_t mpls_ttl; // transport layer uint16_t tp_src; uint16_t tp_dst; diff --git a/ZodiacFX/src/openflow/openflow_13.c b/ZodiacFX/src/openflow/openflow_13.c index c6ed7f9..9168207 100644 --- a/ZodiacFX/src/openflow/openflow_13.c +++ b/ZodiacFX/src/openflow/openflow_13.c @@ -293,29 +293,42 @@ void nnOF13_tablelookup(uint8_t *p_uc_data, uint32_t *ul_size, int port) mpls[2] &= 0xFE; // clear bottom stack bit } struct ofp13_action_push *push = (struct ofp13_action_push*)act_hdr; - uint16_t payload_offset = fields.payload - p_uc_data; - memmove(fields.payload + 4, fields.payload, packet_size - payload_offset); + memmove(fields.payload + 4, fields.payload-2, packet_size - 12); memcpy(fields.payload - 2, &push->ethertype, 2); memcpy(fields.payload, mpls, 4); - packet_size += 4; - *ul_size += 4; + fields.payload += 6; + packet_size += 6; + *ul_size += 6; fields.eth_prot = push->ethertype; + fields.isMPLSTag = true; } break; // Pop an MPLS tag case OFPAT13_POP_MPLS: - if(fields.eth_prot == htons(0x8847) || fields.eth_prot == htons(0x8848)){ + if(fields.isMPLSTag){ struct ofp13_action_pop_mpls *pop = (struct ofp13_action_pop_mpls*)act_hdr; - uint16_t payload_offset = fields.payload - p_uc_data; - memmove(fields.payload, fields.payload + 4, packet_size - payload_offset - 4); - memcpy(fields.payload - 2, &pop->ethertype, 2); - packet_size -= 4; - *ul_size -= 4; + memmove(p_uc_data+12, p_uc_data+18, packet_size-18); + fields.payload -= 6; + packet_size -= 6; + *ul_size -= 6; packet_fields_parser(p_uc_data, &fields); } break; + // Set MPLS TTL + case OFPAT13_SET_MPLS_TTL: + { + struct ofp13_action_mpls_ttl *act_mpls_ttl = act_hdr; + if(fields.isMPLSTag) + { + p_uc_data[17] = act_mpls_ttl->mpls_ttl; + fields.mpls_ttl = act_mpls_ttl->mpls_ttl; + TRACE("Set MPLS TTL %d", fields.mpls_ttl); + } + } + break; + // Set Field Action case OFPAT13_SET_FIELD: { @@ -327,8 +340,8 @@ void nnOF13_tablelookup(uint8_t *p_uc_data, uint32_t *ul_size, int port) switch(oxm_header.oxm_field) { // Set VLAN ID + // The use of a set-field action assumes that the corresponding header field exists in the packet case OFPXMT_OFB_VLAN_VID: - // SPEC: The use of a set-field action assumes that the corresponding header field exists in the packet if(fields.isVlanTag){ memcpy(oxm_value, act_set_field->field + sizeof(struct oxm_header13), 2); p_uc_data[14] = (p_uc_data[14] & 0xf0) | (oxm_value[0] & 0x0f); @@ -345,6 +358,41 @@ void nnOF13_tablelookup(uint8_t *p_uc_data, uint32_t *ul_size, int port) TRACE("Set VLAN_PCP %u", oxm_value[0]); } break; + + // Set MPLS + // The use of a set-field action assumes that the corresponding header field exists in the packet + case OFPXMT_OFB_MPLS_LABEL: + if(fields.eth_prot == htons(0x8847) || fields.eth_prot == htons(0x8848)){ + memcpy(oxm_value, act_set_field->field + sizeof(struct oxm_header13), 4); + memcpy(&fields.mpls_label, oxm_value, 4); + uint32_t label = ntohl(fields.mpls_label)<<4; + label = ntohl(label); + memcpy(oxm_value, &label, 4); + p_uc_data[14] = oxm_value[1]; + p_uc_data[15] = oxm_value[2]; + p_uc_data[16] |= oxm_value[3]; + TRACE("Set MPLS Label %u", ntohl(fields.mpls_label)); + } + break; + + case OFPXMT_OFB_MPLS_TC: + if(fields.eth_prot == htons(0x8847) || fields.eth_prot == htons(0x8848)){ + memcpy(oxm_value, act_set_field->field + sizeof(struct oxm_header13), 1); + p_uc_data[16] |= (oxm_value[0]<<1); + memcpy(&fields.mpls_tc, oxm_value, 1); + TRACE("Set MPLS TC %d", fields.mpls_tc); + } + break; + + case OFPXMT_OFB_MPLS_BOS: + if(fields.eth_prot == htons(0x8847) || fields.eth_prot == htons(0x8848)){ + memcpy(oxm_value, act_set_field->field + sizeof(struct oxm_header13), 1); + if (oxm_value[0] == 1) p_uc_data[16] |= 1; + if (oxm_value[0] == 0) p_uc_data[16] &= 0; + memcpy(&fields.mpls_bos, oxm_value, 1); + TRACE("Set MPLS %u", fields.mpls_bos); + } + break; // Set Source Ethernet Address case OFPXMT_OFB_ETH_SRC: @@ -530,7 +578,7 @@ void nnOF13_tablelookup(uint8_t *p_uc_data, uint32_t *ul_size, int port) } if (recalculate_ip_checksum) { - set_ip_checksum(p_uc_data, packet_size, fields.payload + 14); + set_ip_checksum(p_uc_data, packet_size, fields.payload - p_uc_data); } } @@ -2486,7 +2534,7 @@ void flowrem_notif13(int flowid, uint8_t reason) ofr.header.type = OFPT13_FLOW_REMOVED; ofr.header.version = OF_Version; - ofr.header.length = htons((sizeof(struct ofp13_flow_removed) + ntohs(flow_match13[flowid]->match.length)-4)); + ofr.header.length = htons((sizeof(struct ofp13_flow_removed)-4) + ntohs(flow_match13[flowid]->match.length)); ofr.header.xid = 0; ofr.cookie = flow_match13[flowid]->cookie; ofr.reason = reason; @@ -2505,7 +2553,7 @@ void flowrem_notif13(int flowid, uint8_t reason) { memcpy(flow_rem + (sizeof(struct ofp13_flow_removed)-4), ofp13_oxm_match[flowid], ntohs(flow_match13[flowid]->match.length)-4); } - sendtcp(&flow_rem, htons(ofr.header.length)); + sendtcp(&flow_rem, htons(ofr.header.length)-4); TRACE("openflow_13.c: Flow removed notification sent"); return; }