odp-util: Format and scan multiple MPLS labels.
[cascardo/ovs.git] / lib / sflow_receiver.c
index 0e34959..cde1359 100644 (file)
@@ -1,5 +1,11 @@
-/* Copyright (c) 2002-2009 InMon Corp. Licensed under the terms of the InMon sFlow licence: */
-/* http://www.inmon.com/technology/sflowlicense.txt */
+/* Copyright (c) 2002-2009 InMon Corp. Licensed under the terms of either the
+ *   Sun Industry Standards Source License 1.1, that is available at:
+ *    http://host-sflow.sourceforge.net/sissl.html
+ * or the InMon sFlow License, that is available at:
+ *    http://www.inmon.com/technology/sflowlicense.txt
+ */
+
+#ifndef __CHECKER__            /* Don't run sparse on anything in this file. */
 
 #include <assert.h>
 #include "sflow_api.h"
@@ -192,6 +198,10 @@ inline static void putString(SFLReceiver *receiver, SFLString *s)
     putNet32(receiver, s->len);
     memcpy(receiver->sampleCollector.datap, s->str, s->len);
     receiver->sampleCollector.datap += (s->len + 3) / 4; /* pad to 4-byte boundary */
+    if ((s->len % 4) != 0){
+        u_int8_t padding = 4 - (s->len % 4);
+        memset(((u_int8_t*)receiver->sampleCollector.datap)-padding, 0, padding);
+    }
 }
 
 inline static u_int32_t stringEncodingLength(SFLString *s) {
@@ -217,9 +227,10 @@ inline static u_int32_t addressEncodingLength(SFLAddress *addr) {
     return (addr->type == SFLADDRESSTYPE_IP_V6) ? 20 : 8;  // type + address (unspecified == IPV4)
 }
 
-inline static void putMACAddress(SFLReceiver *receiver, u_int8_t *mac)
+inline static void putMACAddress(SFLReceiver *receiver,
+                                 const struct eth_addr mac)
 {
-    memcpy(receiver->sampleCollector.datap, mac, 6);
+    memcpy(receiver->sampleCollector.datap, &mac, 6);
     receiver->sampleCollector.datap += 2;
 }
 
@@ -454,6 +465,14 @@ static int computeFlowSampleSize(SFLReceiver *receiver, SFL_FLOW_SAMPLE_TYPE *fs
        case SFLFLOW_EX_MPLS_FTN: elemSiz = mplsFtnEncodingLength(&elem->flowType.mpls_ftn); break;
        case SFLFLOW_EX_MPLS_LDP_FEC: elemSiz = mplsLdpFecEncodingLength(&elem->flowType.mpls_ldp_fec); break;
        case SFLFLOW_EX_VLAN_TUNNEL: elemSiz = vlanTunnelEncodingLength(&elem->flowType.vlan_tunnel); break;
+       case SFLFLOW_EX_IPV4_TUNNEL_EGRESS:
+       case SFLFLOW_EX_IPV4_TUNNEL_INGRESS:
+           elemSiz = sizeof(SFLSampled_ipv4);
+           break;
+       case SFLFLOW_EX_VNI_EGRESS:
+       case SFLFLOW_EX_VNI_INGRESS:
+           elemSiz = sizeof(SFLExtended_vni);
+           break;
        default:
            sflError(receiver, "unexpected packet_data_tag");
            return -1;
@@ -550,6 +569,8 @@ int sfl_receiver_writeFlowSample(SFLReceiver *receiver, SFL_FLOW_SAMPLE_TYPE *fs
                putNet32(receiver, elem->flowType.ethernet.eth_type);
                break;
            case SFLFLOW_IPV4:
+           case SFLFLOW_EX_IPV4_TUNNEL_EGRESS:
+           case SFLFLOW_EX_IPV4_TUNNEL_INGRESS:
                putNet32(receiver, elem->flowType.ipv4.length);
                putNet32(receiver, elem->flowType.ipv4.protocol);
                put32(receiver, elem->flowType.ipv4.src_ip.addr);
@@ -581,6 +602,11 @@ int sfl_receiver_writeFlowSample(SFLReceiver *receiver, SFL_FLOW_SAMPLE_TYPE *fs
            case SFLFLOW_EX_MPLS_FTN: putMplsFtn(receiver, &elem->flowType.mpls_ftn); break;
            case SFLFLOW_EX_MPLS_LDP_FEC: putMplsLdpFec(receiver, &elem->flowType.mpls_ldp_fec); break;
            case SFLFLOW_EX_VLAN_TUNNEL: putVlanTunnel(receiver, &elem->flowType.vlan_tunnel); break;
+           case SFLFLOW_EX_VNI_EGRESS:
+           case SFLFLOW_EX_VNI_INGRESS:
+               putNet32(receiver, elem->flowType.tunnel_vni.vni);
+               break;
+
            default:
                sflError(receiver, "unexpected packet_data_tag");
                return -1;
@@ -619,11 +645,16 @@ static int computeCountersSampleSize(SFLReceiver *receiver, SFL_COUNTERS_SAMPLE_
        cs->num_elements++;
        siz += 8; /* tag, length */
        switch(elem->tag) {
-       case SFLCOUNTERS_GENERIC:  elemSiz = sizeof(elem->counterBlock.generic); break;
-       case SFLCOUNTERS_ETHERNET: elemSiz = sizeof(elem->counterBlock.ethernet); break;
+       case SFLCOUNTERS_GENERIC:  elemSiz = SFL_CTR_GENERIC_XDR_SIZE; break;
+       case SFLCOUNTERS_ETHERNET: elemSiz = SFL_CTR_ETHERNET_XDR_SIZE; break;
        case SFLCOUNTERS_TOKENRING: elemSiz = sizeof(elem->counterBlock.tokenring); break;
        case SFLCOUNTERS_VG: elemSiz = sizeof(elem->counterBlock.vg); break;
        case SFLCOUNTERS_VLAN: elemSiz = sizeof(elem->counterBlock.vlan); break;
+       case SFLCOUNTERS_LACP: elemSiz = SFL_CTR_LACP_XDR_SIZE; break;
+       case SFLCOUNTERS_OPENFLOWPORT: elemSiz = SFL_CTR_OPENFLOWPORT_XDR_SIZE; break;
+       case SFLCOUNTERS_PORTNAME: elemSiz = stringEncodingLength(&elem->counterBlock.portName.portName); break;
+       case SFLCOUNTERS_APP_RESOURCES: elemSiz = SFL_CTR_APP_RESOURCES_XDR_SIZE; break;
+       case SFLCOUNTERS_OVSDP: elemSiz = SFL_CTR_OVSDP_XDR_SIZE; break;
        default:
            sflError(receiver, "unexpected counters_tag");
            return -1;
@@ -725,6 +756,45 @@ int sfl_receiver_writeCountersSample(SFLReceiver *receiver, SFL_COUNTERS_SAMPLE_
                putNet32(receiver, elem->counterBlock.vlan.broadcastPkts);
                putNet32(receiver, elem->counterBlock.vlan.discards);
                break;
+           case SFLCOUNTERS_LACP:
+               putMACAddress(receiver, elem->counterBlock.lacp.actorSystemID);
+               putMACAddress(receiver, elem->counterBlock.lacp.partnerSystemID);
+               putNet32(receiver, elem->counterBlock.lacp.attachedAggID);
+               put32(receiver, elem->counterBlock.lacp.portState.all);
+               putNet32(receiver, elem->counterBlock.lacp.LACPDUsRx);
+               putNet32(receiver, elem->counterBlock.lacp.markerPDUsRx);
+               putNet32(receiver, elem->counterBlock.lacp.markerResponsePDUsRx);
+               putNet32(receiver, elem->counterBlock.lacp.unknownRx);
+               putNet32(receiver, elem->counterBlock.lacp.illegalRx);
+               putNet32(receiver, elem->counterBlock.lacp.LACPDUsTx);
+               putNet32(receiver, elem->counterBlock.lacp.markerPDUsTx);
+               putNet32(receiver, elem->counterBlock.lacp.markerResponsePDUsTx);
+               break;
+           case SFLCOUNTERS_OPENFLOWPORT:
+               putNet64(receiver, elem->counterBlock.ofPort.datapath_id);
+               putNet32(receiver, elem->counterBlock.ofPort.port_no);
+               break;
+           case SFLCOUNTERS_PORTNAME:
+               putString(receiver, &elem->counterBlock.portName.portName);
+               break;
+           case SFLCOUNTERS_APP_RESOURCES:
+               putNet32(receiver, elem->counterBlock.appResources.user_time);
+               putNet32(receiver, elem->counterBlock.appResources.system_time);
+               putNet64(receiver, elem->counterBlock.appResources.mem_used);
+               putNet64(receiver, elem->counterBlock.appResources.mem_max);
+               putNet32(receiver, elem->counterBlock.appResources.fd_open);
+               putNet32(receiver, elem->counterBlock.appResources.fd_max);
+               putNet32(receiver, elem->counterBlock.appResources.conn_open);
+               putNet32(receiver, elem->counterBlock.appResources.conn_max);
+               break;
+           case SFLCOUNTERS_OVSDP:
+               putNet32(receiver, elem->counterBlock.ovsdp.n_hit);
+               putNet32(receiver, elem->counterBlock.ovsdp.n_missed);
+               putNet32(receiver, elem->counterBlock.ovsdp.n_lost);
+               putNet32(receiver, elem->counterBlock.ovsdp.n_mask_hit);
+               putNet32(receiver, elem->counterBlock.ovsdp.n_flows);
+               putNet32(receiver, elem->counterBlock.ovsdp.n_masks);
+               break;
            default:
                sflError(receiver, "unexpected counters_tag");
                return -1;
@@ -830,3 +900,5 @@ static void sflError(SFLReceiver *receiver, char *msg)
     sfl_agent_error(receiver->agent, "receiver", msg);
     resetSampleCollector(receiver);
 }
+
+#endif  /* !__CHECKER__ */