The ONL Tutorial

Tutorial >> Summary Information TOC

Summary of SPC Macros And Functions

Packet Buffers

A packet buffer is always 2 KB and contains an AAL5 frame. Figure 1 shows a typical packet buffer with the intraport shim immediately followed by an IP datagram. The plugin's handle_packet routine is passed a reference to a list of packet buffer descriptors with each buffer descriptor referencing exactly one packet buffer. While there will never be more than one packet on the list passed to the handle_packet method, a tail queue is used to permit the plugin to pass zero, one or more packets back to the calling environment.


Intraport Shim

The intraport shim is a 16-byte field that contains information used by the SPC and FPX for determining the disposition of a given packet. The shim fields shown in Fig. 1 with the grey diagonal lines are reserved for the internal use of the FPX and SPC and should not be used by the plugin. The remaining fields are available to the plugin and have the following meanings:

The remaining shim fields (PPN, TTL chunks, Packet pointer and Second chunk pointer) should not be referenced or used by plugins. For more information see the header file ~onl/wu_arl/msr/usr/src/sys/msr/shim.h.

Fig. 1: Example Packet buffer contents showing the intraport shim and IP Datagram

Allocating packet buffers

When a new packet buffer is allocated the shim is initialized such that the packet appears to have been received by the local port. In addition the reclassify bit is set to that the FPX will classify the packet and forward as usual. If however the programmer wants to explicitly set the ovin and qid values then the recalssify bit (RC flag) must be cleared. In summary, the programmer should do the following:

Shim Macros and Functions

The following are either macros (#define) or static inline functions. In the case of macros, the return type specified below is not really precise, but I have tried to specify what type is typically used in Get-type operations (e.g., msr_vin_get) and used void in Set-type operations. The interface is divided into two parts, the first lists functions and macros which provide simplified wrappers to common operations. The second is a list of low level operations to manipulate bit fields and request system services.

From ~onl/wu_arl/msr/rp/plugins/include/plugin_utils.h:

Synopsis

Description

HDRQ_t *msr_plist2Hlist(void *bufList);

Simply casts bufList to the proper type.

msr_bufhdr_t *msr_firstBuffer(void *bufList);

Returns the first buffer in the list. This does not remove the buffer, rather it returns a reference to the buffer which remains on the bufList.

msr_bufhdr_t *msr_nextBuffer(msr_bufhdr_t *curBuf);

Returns a reference to the buffer immediately following curBuf in the input bufList.

void msr_removeBuffer(void *bufList, msr_bufhdr_t *curBuf);

Removes curBuf from the associated buffer list (bufList).

void msr_freeBuffer(msr_bufhdr_t *curBuff);

Deallocates memory for both the packet buffer and its descriptor (msr_bufhdr_t)

msr_IntraPortShim_t *msr_buf2Shim(msr_bufhdr_t *hdr);

Simply returns a reference to the intraport shim cast to type msr_IntraPortShim_t (see msr_shim.h). This is a C struct that uses bit fields to simply access to the shim fields. Alternatively a programmer may choose to use the less friendly bit shifting macros defined in msr_shim.h (see below).

From ~onl/wu_arl/msr/usr/src/sys/msr/msr_shim.h

Synopsis

Description

u_int32_t msr_vin_get_pn(unsigned int vin)

Get VIN's port number

u_int32_t msr_vin_set_pn(v,p)

Set VIN's port number to p

u_int32_t msr_vin_make(p,s)

Create vin with port p, subport s
(subport should always be 0)

uint msr_shim_get_qid(MSR_Shim_t *shim)

Get shim's QID

void msr_shim_set_qid (MSR_Shim_t *shim, unsigned int val)

Set shim's QID to val

uint msr_shim_get_ppn(MSR_Shim_t *shim)

Get shim's PPN

void msr_shim_set_ppn (MSR_Shim_t *shim, unsigned int val)

Set shim's PPN to val

uint msr_shim_get_ovin(MSR_Shim_t *shim)

Get shim's OVIN

void msr_shim_set_ovin (MSR_Shim_t *shim, unsigned int val)

Set shim's OVIN to val

uint msr_shim_get_ivin(MSR_Shim_t *shim)

Get shim's IVIN

void msr_shim_set_ivin (MSR_Shim_t *shim, unsigned int val)

Set shim's IVIN to val

uint msr_shim_get_flags(MSR_Shim_t *shim)

Get shim's flags

void msr_shim_set_flags (MSR_Shim_t *shim, unsigned int val)

Set shim's flags to val

void msr_shim_hton(MSR_Shim_t *shim)

Convert shim from HBO to NBO

void msr_shim_ntoh(MSR_Shim_t *shim)

Convert shim from NBO to HBO

int msr_shim_flagon (MSR_Shim_t *shim, int flag)

Return flag (0 or 1)

u_int32_t msr_shim_set_flag (MSR_Shim_t *shim, int flag)

Set an MSR flag

u_int32_t msr_shim_unset_flag (MSR_Shim_t *shim, int flag)

Unset an MSR flag

msr_print_shim (char *str, int len, MSR_Shim_t *shim)

Return string with shim's info



Shim Flags

MSR_SHIM_FLAGS_DP

0x80

Drop Packet; set by SPC

MSR_SHIM_FLAGS_RC

0x40

Reclassify; Set by SPC

MSR_SHIM_FLAGS_NM

0x20

No Match; set by FPX

MSR_SHIM_FLAGS_EX

0x10

Exception Packet; set by FPX

MSR_SHIM_FLAGS_FM

0x02

From LC/SW; FPX internal

MSR_SHIM_FLAGS_TO

0x01

To 1 => LC; 0 => SW; FPX internal

MSR_SHIM_FLAGS_TO_LC

1


MSR_SHIM_FLAGS_TO_SW

0


IP Header and Forwarding Macros and Functions

From ~onl/wu_arl/msr/usr/src/sys/msr/msr_ip.h

Synopsis

Description

msr_rt_get_vin(u_int32_t rt)

Used to extract the output port and subport numbers (i.e. output VIN) from a router entry.

msr_rt_set_vin(rt, v)

A preprocessor macro which updates the output VIN contained in the rt (route) entry.

msr_rt_get_qid(u_int32_t rt)

Returns the qid from the route entry rt.

msr_rt_set_qid(u_int32_t rt, q)

Updates the gid field of the route entry rt.

int msr_iplen(struct ip *iph)

Reads the datagram length field of the ip header and returns the byte count in host byte order (HBO).

int msr_iphlen(struct ip *iph)

Reads the header length field oh the ip header and returns the value in host byte order (HBO).

u_int32_t msr_ipdaddr(struct ip *iph)

Reads the ip destination address contained in the ip header and returns it in host byte order (HBO).

u_int32_t msr_ipsaddr(struct ip *iph)

Reads the ip source address contained in the ip header and returns it in host byte order (HBO).

int msr_ipproto(struct ip *iph)

Reads the protocol field (1 Byte field) in the ip header and returns it as a 4-Byte integer in host byte order (HBO).

u_int16_t msr_ipdport(struct ip *iph)

Reads the destination port number in the ip header and returns it in host byte order (HBO).

u_int16_t msr_ipsport(struct ip *iph)

Reads the source port number in the ip header and returns it in host byte order (HBO).

struct ip * msr_pkt_iph(msr_bufhdr_t *hdr)

Given a pointer to the buffer descriptor this function returns a pointer to the start of the ip header.

MSR_Shim_t * msr_pkt_shim(msr_bufhdr_t *hdr)

Given a pointer to the buffer descriptor this function returns a pointer to the start of the intra-port shim.

u_int32_t msr_rt_mkfwdkey(u_int32_t qid, u_int32_t vin)

Return a u_int32_t route entry with the qid and vin fields set

int msr_hasports(struct ip *iph)

Return 1 if pkt is UDP or TCP pkt and if pkt's fragmentation offset is 0

char * msr_print_iph(char *str, int len, struct ip *iph)

Return string containing IP header's info .

int msr_isfrag(struct ip *iph)

Returns 1 if the packet is an ip fragment, otherwise returns 0.

int msr_first_frag(struct ip *iph)

Returns 1 if the packet corresponds to a fragmented IP datagram and this is the first fragment, otherwise returns 0.

int msr_last_frag(struct ip *iph)

Returns 1 if the packet corresponds to a fragmented IP datagram and this is the last fragment, otherwise returns 0.

SPC Clock Macros and Functions

From ~onl/wu_arl/msr/usr/src/sys/msr/{msr_lkm.h,msr.c}

Synopsis

Description

u_int32_t PLUGIN_CPU_CLOCK_1MSEC_FCT(void)

Returns the number of miliseconds elapsed since the counter was initialized.

int PLUGIN_MSR_TICKSIZE_FCT(void)

Returns the msr clock period in microseconds.

int PLUGIN_MSR_USEC2TICKS_FCT(int us)

Converts from microseconds to the corresponding number of SPC clock ticks. If the usec argument is not a multiple of the tick rate then the requested value is rounded up. For example if the clock period is 500us (the default frequency is 2000Hz) and the programmer calls PLUGIN_MSR_USEC2TICKS_FCT with an argument of 501us the value 2 is returned (i.e. 2 ticks).

int PLUGIN_MSR_CLOCK_HANDLER_FCT(void (*h)(void), int id, int t)

Used to insert a user defined handler which is called periodically every t clock ticks. The id parameter should always be set to MSR_CLOCK_HANDLER_PCU_ID. Returns -1 if the handler could not be installed, usually indicates an improper id value. On success the id parameter is returned.

int PLUGIN_MSR_HANDLER_RESET_FCT(int id, int ticks)

Used to change a handlers callback rate. If ticks = 0 then the handler is deregistered. Returns -1 if the id value in invalid otherwise returns the id value.

From ~onl/wu_arl/msr/usr/src/sys/msr/msr_lkm.{h,c}

Synopsis

Description

int PLUGIN_SNPRINTF(char *, size_t, const char *, ...);

Export of the kernel's version of snprintf().

char *PLUGIN_STRCAT((char *, const char *)

Export of the kernel's version of strcat().

char *PLUGIN_STRNCPY(char *, const char *, size_t)

Export of the kernel's version of strncpy().

size_t PLUGIN_STRLEN(const char *)

Export of the kernel's version of strlen().

MSR_PLUGIN_MALLOC(space, cast, size, type, flags);

Export of kernel's malloc macro. The space argument is a pointer which will be initialized to reference the allocated memory. The cast argument is the corresponding type. The size argument is the number of bytes to allocate, type should always be M_MSR and flags should be set to M_WAITOK or M_NOWAIT. On error the space argument is set to NULL.

void PLUGIN_FREE(void *addr, int type)

Export of kernel's free function (used to free memory allocated by MSR_PLUGIN_MALLOC). The type should always be set to M_MSR.

void PLUGIN_MSR_PRINTF_FCT(const u_int32_t , const char *,...)

This function is for printing debug messages. The first argument is a bitwise or of the module (MSR_DEBUG_PLUGIN) and level. See msr_debug.h for valid levels.

void PLUGIN_PRINT_HDR_FCT(car *s, u_int32_t f, char *a)

This uses the MSR_DEBUG facility to print the contents of the msr_bufhdr_t struct referenced by argument a. The argument s should either be set to NULL or reference a valid which is prepended to the output message. The argument f are MSR_DEBUG flags and should be set to the bitwise or of MSR_DEBUG_PLUGIN and the desired verbosity level (such as MSR_DEBUG_LEVEL_INFO).

msr_bufhdr_t *PLUGIN_IPBUF_ALLOC_FCT(void)

This allocates both a packet buffer and the corresponding buffer descriptor (msr_bufhdr_t). The returned buffer includes a shim which has been initialized to mimic a packet which was received on associated port and has not yet been classified (i.e. the reclassify bit is set). Null (0) is returned if no buffers are available.

void PLUGIN_IPBUF_FREE_FCT(msr_bufhdr_t *)

Deallocates the referenced packet buffer and returns it to the free list. This function must not be called with a NULL pointer, the function void msr_freeBuffer(msr_bufhdr_t *) defined in $MSR/rp/plugins/include/plugin_utils.h adds a level of error checking by first checking for a NULL pointer before calling PLUGIN_IPBUF_FREE_FCT().

int PLUGIN_MSR_CFY_FADD_FCT(int c, MSR_GenFilter_t *f, CFY_FltrParams_t *p)

Used to add general or exact match filters to the classifier in the FPX. The parameter c should be either MSR_CFY_ID_EXACT or MSR_CFY_ID_GENERAL for exact match or general match filters respecively. The parameter f specifies the matching header values and parameter p the desired qid and priority. See msr_classify.h for a description of the data structures. A return value of zero indicates success and less than zero an error. The error codes are defined in msr_classify.h with an error return equaling the negative of the defined constants. For example, if invalid arguments are supplied then -1 * MSR_CFY_RESULT_InvArgs is returned.

int PLUGIN_MSR_CFY_FREM_FCT(int c, MSR_GenFilter_t *f, CFY_FltrParams_t *p)

Removes a filter installed either by PLUGIN_MSR_CFY_FADD_FCT() or the RLI. See msr_classify.h for a description of the data structures. Returns zero on success or a negative error code (see msr_classify.h for a list of error codes).

int PLUGIN_MSR_CKSUM_FCT(char *, int)

Used to calculate the IP header checksum in the SPC's kernel code. Plugin developers should use the functions defined in $MSR/rp/plugins/include/ipnet.h (see calc_cksums()) which updates the checksum of both the IP and transport (UDP or TCP) checksum headers fields.

int PLUGIN_IP_FWD_FCT(msr_bufhdr_t *hdr)

A plugin may choose to directly forward a packet rather than adding it to the packet list passed to the plugin's handle_packet routine. If a packet is forwarded using PLUGIN_IP_FWD_FCT then it must not also appear on the bufferList. Returns zero if packet is successfully enqueued for delivery to the FPX, otherwise -1 is returned.

int PLUGIN_SPLCLOCK_FCT(void)

Calling this function will disable clock interrupts, used to protect critical sections when a plugin also uses the clock handler (which runs at the clock interrupt priority). Should always be followed with a call to PLUGIN_SPLX_FCT at the end of a critical section. The return value is an encoding of the current system priority level and must be used in a matching call to PLUGIN_SPLX_FCT().

void PLUGIN_SPLX_FCT(int s)

Enables clock interrupts. The parameter s is set from a call to PLUGIN_SPLCLOCK_FCT().

    	s = PLUGIN_SPLCLOCK_FCT();
    	// critical section
    	PLUGIN_SPLX_FCT()
    	

MSR_PLUGIN_DISPATCH(struct lkm_table *lkmtp, int cmd, int ver, int (*_load) __P((struct lkm_table *lkmtp, int cmd)), int (*_unload) __P((struct lkm_table *lkmtp, int cmd)), int (*_stat) __P((struct lkm_table *lkmtp, int cmd)) )

Called as the very last thing in a plugin modules entry point function. This DISPATCH function causes the plugins _load, _unload or _stat function to be called in response to a command. Often the _stat module is not needed and its place is filled in by the dummy function PLUGIN_LKM_NOFUNC_FCT described below. The use of MSR_PLUGIN_DISPATCH and the PLUGIN_LKM_*_FCT macros/functions would need to be changed very rarely from what is given in the stdplugins and templates.

PLUGIN_LKM_NOFUNC_FCT(struct lkm_table *lkmtp, int cmd)

Can be used as a placeholder for functions passed to the MSR_PLUGIN_DISPATCH function. PLUGIN_LKM_NOFUNC_FCT simply returns 0.

PLUGIN_LKM_DISPATCH_FCT(struct lkm_table *lkmtp, int cmd)

Called as the very last thing in MSR_PLUGIN_DISPATCH. This function calls the kernel functions to do load, unload and stat for special types of modules (LM_VFS, LM_SYSCALL, LM_DEV, ...). For our plugins (type=LM_MISC), this is handled in MSR_PLUGIN_DISPATCH.

PLUGIN_LKM_EXISTS_FCT(struct lkm_table *lkmtp)

Called by a plugin's _load function to avoid loading the plugin twice. Returns one if a plugin of same name is already loaded, otherwise returns zero.

int PLUGIN_PCU_DEREGISTER_CLASS_FCT(struct rp_class *)

Called by a plugin to deregister a class with the SPC plugin control unit. Returns zero (RP_OK) on success, otherwise an error code less than zero is returned. See rp.h for a list of error codes.

int PLUGIN_PCU_FREE_ALL_INSTANCES_FCT(struct rp_class *)

Used by a plugin class to forciblE free any plugin instances. Should be called form the plugin's unload class function to ensure all instances are freed. Returns zero (RP_OK) on success, otherwise an error code less than zero is returned. See rp.h for a list of error codes.

int PLUGIN_PCU_REGISTER_CLASS_FCT(struct rp_class *)

Called by a classes load function to register itself with the SPC plugin control unit. Returns zero (RP_OK) on success, otherwise an error code less than zero is returned. See rp.h for a list of error codes.

void PLUGIN_PCU_LIST_ALL_CLASSES_FCT(void)

Debugging utility which prints a list of loaded classes to the debug messaging facility (also known as monmsgs).

int PLUGIN_MSR_NSP_FPX_READ_REGISTER(u_int8_t regId, u_int32_t *regValue, u_int32_t *timeStamp)

Reads fpx register with id reqID and returns the value in regValue.

int PLUGIN_MSR_NSP_FPX_READ_COUNTER(u_int8_t ctrNum, u_int32_t *ctrValue, u_int32_t *timeStamp)

Reads FPX counter ctrNum and returns the value in ctrValue and timestamp in timeStamp.

int PLUGIN_MSR_NSP_FPX_READ_QUEUE_LENGTH(u_int16_t qid, u_int32_t *qlength, u_int32_t *timeStamp)

Reads the queue length in bytes of qid, returned in network byte order.

int PLUGIN_MSR_NSP_FPX_READ_VOQ_LENGTH(u_int32_t *qlengths, u_int32_t *totalEgressQlength, u_int32_t *timeStamp)

Returns the virtual output queue lengths in the array qlengths, total length of all egress queues in totalEgressQlength and timestamp in timeStamp. The array qlenths is indexed by voq id (0 - 7), and all queue lengths are in network byte order.


  

Tutorial >> Summary Information TOC