EXOS Native Application SDK Introduction and User’s Guide Extreme Networks Version 0.3 03/10/2011 Extreme Networks Confidential c 2010,2011 Extreme Networks, Inc. Copyright DR AF T All Rights Reserved. 2 Extreme Networks Confidential Contents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 Creating an EXOS Application 2.1 Overview . . . . . . . . . . . . . . . . 2.2 Application Development Process . . 2.3 EXOS Architecture . . . . . . . . . . 2.4 Directory Structure . . . . . . . . . . 2.5 CLI Definition File . . . . . . . . . . 2.6 Configuration Object Definition File 2.7 Module Specification File . . . . . . . 2.8 Process Definition File . . . . . . . . 2.9 Application Source Code . . . . . . . 2.10 Makefile . . . . . . . . . . . . . . . . 2.11 Application Version File . . . . . . . 2.12 Building and Installation . . . . . . . 2.13 OK, I’ve Installed It... Now What? . 2.14 Looking Forward . . . . . . . . . . . 3 Adding Some Functionality 3.1 Overview . . . . . . . . . . 3.2 A Minimal SMTP Client . 3.3 Dispatcher Timers . . . . 3.4 Putting it All Together . . 3.5 The EMS Trace Facility . 3.6 Non-Blocking Sockets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . T . . . . . . . DR AF 1 Getting Started 1.1 Introduction . . . . . . . 1.2 Package Contents . . . . 1.3 System Requirements . . 1.4 Supported Platforms . . 1.5 Installation . . . . . . . 1.6 SDK Directory Structure 1.7 Looking Forward . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 9 9 10 10 10 10 11 . . . . . . . . . . . . . . 13 13 13 14 15 16 16 16 17 18 21 22 22 23 23 . . . . . . 25 25 25 28 28 29 31 CONTENTS and Configuration Overview . . . . . . . . . . . . . EXOS CLI Architecture . . . . Defining Configuration Objects Get/Set Method Support . . . . CLI Definition File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 33 33 35 36 38 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 43 43 43 43 48 49 50 6 VLAN Manager 6.1 Overview . . . . . . . . . . . . . . . . 6.2 VLAN Manager API . . . . . . . . . 6.3 Using VLAN Manager APIs . . . . . 6.4 The VLAN Manager APIs in Action . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 51 51 51 53 . . . . 55 55 55 55 56 8 L2 Packet Handling 8.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.2 Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 57 57 9 Linux Kernel Modules 9.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.2 Kernel Module Makefile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.3 Trivial Kernel Module Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 65 65 65 . . . . . . . DR AF 5 Adding EMS Support 5.1 Overview . . . . . . . . . . . . 5.2 EXOS EMS Architecture . . . 5.3 Event Definition File Naming 5.4 Event Definition File Content 5.5 Makefile Changes . . . . . . . 5.6 Source Code Changes . . . . . 5.7 Adding Event Logging . . . . T 4 CLI 4.1 4.2 4.3 4.4 4.5 CONTENTS 7 FDB Manager 7.1 Overview . . . . . . . . . . . . . . . 7.2 FDB Manager API . . . . . . . . . 7.3 Using FDB Manager APIs . . . . . 7.4 The FDB Manager APIs in Action . . . . . . . . . . . . 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Extreme Networks Confidential List of Figures SDK Directory Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 2.1 Module Creation Process . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 4.1 Configuration Message Flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 5.1 5.2 5.3 EMS Event Editor Initial Screen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EMS Event Editor with First Event Information . . . . . . . . . . . . . . . . . . . . EMS Event Editor with Second Event Information . . . . . . . . . . . . . . . . . . . 44 46 47 DR AF T 1.1 5 LIST OF FIGURES DR AF T LIST OF FIGURES 6 Extreme Networks Confidential Source Code Listings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . T Stub CLI Definition File . . . . . . . . . . . . . . . . . . Stub Configuration Object Definition File . . . . . . . . XMOD ”spec” File . . . . . . . . . . . . . . . . . . . . . Sample epmrc File . . . . . . . . . . . . . . . . . . . . . Configuration Manager Callback for Sample Application Device Manager Callback for Sample Application . . . . Main Application Code for Sample Application . . . . . Makefile for Sample Application . . . . . . . . . . . . . . Version File for Sample Application . . . . . . . . . . . . Mini SMTP Client Source Code . . . . . . . . . . . . . . Mini SMTP Client Header File . . . . . . . . . . . . . . Prototype for dispatchExecuteWorkItem() . . . . . . . . Makefile Modifications . . . . . . . . . . . . . . . . . . . Modifications to sample.c . . . . . . . . . . . . . . . . . . EMS Tracing API . . . . . . . . . . . . . . . . . . . . . . Creating an EMS Trace Buffer . . . . . . . . . . . . . . . Using an EMS Trace Buffer . . . . . . . . . . . . . . . . Formatted Output from an EMS Trace Buffer . . . . . . Configuration Object Definition File . . . . . . . . . . . Preamble for Get and Set Method Implementation . . . . Get Method Implementation . . . . . . . . . . . . . . . . Set Method Implementation . . . . . . . . . . . . . . . . TCL Definition for “configure” Command . . . . . . . . TCL Definition for“show” Command . . . . . . . . . . . XML Definitions for EMS Events . . . . . . . . . . . . . First Makefile Modification (Add Generated Source File) Second Makefile Modification (Define EMS Component) Including sample ems api.h . . . . . . . . . . . . . . . . Initializing EMS client library . . . . . . . . . . . . . . . Adding logging for email events . . . . . . . . . . . . . . VLAN Manager Interface . . . . . . . . . . . . . . . . . . Sample Application Definitions . . . . . . . . . . . . . . FDB Manager Interface . . . . . . . . . . . . . . . . . . Wake-on-LAN Application . . . . . . . . . . . . . . . . . WoL Applications CM Methods . . . . . . . . . . . . . . DR AF 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 4.1 4.2 4.3 4.4 4.5 4.6 5.1 5.2 5.3 5.4 5.5 5.6 6.1 6.2 7.1 8.1 8.2 7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 16 17 17 19 19 20 22 22 25 27 28 28 29 30 30 30 30 35 36 37 38 39 41 47 48 49 49 49 50 52 53 55 57 62 SOURCE CODE LISTINGS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 62 65 65 T WoL Applications CM Object Definiitons WoL Applications CLI Definiitons . . . . Linux Kernel Module Makefile . . . . . . Sample Application Definitions . . . . . DR AF 8.3 8.4 9.1 9.2 SOURCE CODE LISTINGS 8 Extreme Networks Confidential Chapter 1 1.1 T Getting Started Introduction DR AF This document provides an introduction to the development of software applications for Extreme Networks switching products through the use of the ExtremeWare XOS Software Development Kit (EXOS SDK). The EXOS SDK enables the development of a variety of native network-centric applications, including: • Layer 2 protocols. • Routing protocols. • System and network management protocols. • Autoconfiguration features. • Management of connected devices. • Network monitoring. • ... 1.2 Package Contents The EXOS SDK is distributed either electronically or on CD/DVD media in the form of a tarball which includes: • Toolchains for MIPS and x86 architectures. • Header files and libraries necessary for using EXOS APIs. • Makefiles, scripts, and other infrastructure necessary for building EXOS applications. • Tools for debugging applications in the EXOS environment. • Documentation in PDF format. 9 1.3. SYSTEM REQUIREMENTS 1.3 CHAPTER 1. GETTING STARTED System Requirements The recommended system requirements for development using the ExtremeWare XOS SDK are as follows: • Operating System: CentOS 5.4, Ubuntu/Kubuntu 9.10, Ubuntu/Kubuntu 10.4. More recent versions of these distributions may also work. • CPU Architecture: x86 64 (64-bit required). • Free Disk Space: 500 MB. • RAM: 4 GB. T • Software Utilites: – Perl 5, perl-tk module Supported Platforms DR AF 1.4 This SDK supports the development of applications for the following EXOS-based hardware platforms: • Summit family switches (including X150, X250, X330, X450, X460, X480, and X650). • Black Diamond 8K family switches (including BD-8500 and BD-8800 families). 1.5 Installation Assuming the listed minimum system requirements are satisfied, the process of installing the SDK is essentially to: 1. Change working directory to the chosen installation directory. 2. Unpack the SDK tarball using e.g. tar -xvf exos sdk v12 5 1.tgz. 3. Set the environment variable SDKBASE to the absolute path to the chosen installation directory. 1.6 SDK Directory Structure Figure 1.1 illustrates the SDK directory structure beneath the installation directory $SDKBASE. The contents of the subdirectories contained in the diagram are as follows: • /exos: EXOS-specific header files, libraries, and build infrastructure. • /doc: SDK and EXOS documentation. • /samples: Sample EXOS applications, including the tutorial application from this document. 10 Extreme Networks Confidential CHAPTER 1. GETTING STARTED 1.7. LOOKING FORWARD DR AF T • /x-tools: GNU toolchains for i686 and MIPS architectures. Figure 1.1: SDK Directory Structure 1.7 Looking Forward The remainder of this document contains a tutorial describing the implementation of a small EXOS application. Extreme Networks Confidential 11 CHAPTER 1. GETTING STARTED DR AF T 1.7. LOOKING FORWARD 12 Extreme Networks Confidential Chapter 2 2.1 T Creating an EXOS Application Overview 2.2 DR AF This chapter begins a tutorial presentation of the process for creating a working EXOS application. By the conclusion of this chapter, we will have created, built, and installed a minimal EXOS application. The application developed in this chapter will be used as a foundation on which additional features and functionality will be developed in subsequent chapters of this document. Note: for clarity, code presented in this tutorial generally does not include code for error checking or handling of run-time error conditions. Please refer to the appropriate API reference documents for details about potential error conditions that need to be anticipated in production-quality software. Application Development Process Figure 2.1 shows a high-level diagram of the process by which an EXOS application is built from user-provided source files. The types of source files from which an EXOS application is built include: • Source Code: C source and header files for the application (*.c, *.h). • CLI Definitions Command-Line Interface syntax definition and implementation (*.cli). • Configuration Object Definitions Defines structure and content of data objects used by internal interfaces to CLI, XML, and SNMP agents (*.obj). • Event Management Definitions XML definitions for all error/event messages produced by the application (* ems.xml). • MIB Definitions Standard MIB definition files (*.my) and configuration object mapping defintions *.smap) for SNMP MIB implementation. • SOAP XML Schema Schema for external XML interface (*.xsd). • Makefile Controls the build process for the application module. 13 CHAPTER 2. CREATING AN EXOS APPLICATION DR AF T 2.3. EXOS ARCHITECTURE Figure 2.1: Module Creation Process The remainder of this chapter describes the construction of a minimal EXOS application. 2.3 EXOS Architecture EXOS is organized as a collection of loosely-coupled independent processes which interact almost exclusively using the IPML message-based interprocess communication mechanism. EXOS applications are started by the EXOS Process Manager (EPM), which is also responsible for monitoring the health of each application (CPU utilization, memory utilization, liveness checking) and for controlling process termination and restarting. 14 Extreme Networks Confidential CHAPTER 2. CREATING AN EXOS APPLICATION 2.4. DIRECTORY STRUCTURE Internally, EXOS applications use an event-driven architecture with the main event-handling loop implemented in the dispatchHandler() function that is part of the dispatcher library. The following types of events are supported: • IPML connection establishment. • IPML connection termination. • IPML message reception. • Timer expiration. • Arbitrary file descriptor has error status. • Local event injection (immediate work item). T • Arbitrary file descriptor is readable or writable. DR AF All user-provided event handlers are registered as callback functions. It is important for event handling functions to perform their processing and return control to the main dispatcher loop quickly, so blocking system calls and long-running computations must be avoided. The precise definition of what ”quickly” means is application-dependent, but generally speaking an event processing callback should take no more than a few hundred milliseconds, less if the application has more stringent real-time response requirements. During initialization, the following activities are typically performed by an EXOS application: 1. Initialization routines for client libraries that interface with other processes (e.g. EPM, DM, CM, EMS, etc.) are called. These generally include code to establish IPML connections to their respective server processes and register event handlers for these connections. 2. Register application-specific information (e.g. CLI definitions with cliMaster, event message definitions with emsServer, MIBS with snmpSubagent, etc.) 3. Enter infinite dispatcher event handling loop. 2.4 Directory Structure A directory structure in needed in which to contain the various application source files for an application. In this tutorial, we will assume that the root working directory is located at $HOME/sample/ with header files residing in ”$HOME/sample/inc” and source files in ”$HOME/sample/src”. This directory structure (with parallel src/ and inc/ subdirectories) is required because the build infrastructure assumes the existence of these subdirectories. Build output is placed in several subdirectories under $HOME/sample/src/, with most intermediate output going into obj/<platform-name>/ and files to be shipped (e.g. application binaries, CLI definition XML, libraries, etc.) placed under platform-name>/exos. The <platform-name>/release subdirectory is created by the common build infrastructure and used as a location for staging the directory structure used for the final installable module. Extreme Networks Confidential 15 2.5. CLI DEFINITION FILE 2.5 CHAPTER 2. CREATING AN EXOS APPLICATION CLI Definition File The first file to be created is a minimal CLI definition file, which will be named sample/src/sample.cli. The contents of this file are shown in listing 2.1. Source Code Listings 2.1: Stub CLI Definition File 1 %s t y l e =”extreme”% 2 %e n d s t y l e% Because we have not yet defined any CLI commands, the CLI definition file is quite short. Later in this tutorial we will implement a few CLI commands; for now, this file serves as a placeholder. Configuration Object Definition File T 2.6 DR AF The next file to be created is a minimal configuration object definition file. As with the CLI definition file discussed in the previous section, this file is merely a placeholder at this point. The contents of sample/src/sample.obj are shown in listing 2.2. Source Code Listings 2.2: Stub Configuration Object Definition File 1 /∗ C o n f i g u r a t i o n o b j e c t d e f i n i t i o n s ∗/ 2.7 Module Specification File EXOS extensions that are distributed separately from the base installation image are distributed as ”EXOS module” or ”XMOD” files. A module specification file must be created for each XMOD to control the contents and installation requirements specific to the module. The ”Module Specification File”, or ”spec” file, contains information used to install or uninstall an XMOD package under EXOS. The contents of this file include: • The name of the shared library (included in the XMOD) to be used by EPM to perform installation tasks. • The list of files included in the package with installation paths. • Optional scripts to run before and/or after installation. • Optional scripts to run before and/or after uninstallation. • Base image revision identifier for compatibility checking. • MD5 checksums for verification of the installed files. Note that some of the listed items are added to the final ”spec” file during the build process (e.g. MD5 checksums and the base release version), while others are controlled by the base spec file. Listing 2.3 shows the contents of our base ”spec” file, located at sample/spec.sample. 16 Extreme Networks Confidential CHAPTER 2. CREATING AN EXOS APPLICATION 2.8. PROCESS DEFINITION FILE Source Code Listings 2.3: XMOD ”spec” File 1 2 3 4 5 6 i n s t a l l e r =l i b u p g r a d e . s o : d e s c r i p t i o n =”Sample a p p l i c a t i o n ” : f i l e n a m e=e x o s v e r s i o n : p a r t=e x o s : f i l e n a m e =./ b i n / sample : type=b i n : p a r t=e x o s : p r o c=sample : f i l e n a m e =./ c o n f i g / c l i d e f / sample . xml : type=t x t : p a r t=e x o s : p o s t i n s t a l l =/tmp/ upgrade epmrc : The contents of this file are interpreted as follows: T • Line 1 declares the installer library to be libupgrade.so, which is included in the *.xmod package. The libupgrade.so library is generally identical to the one that is included in the base EXOS image, however there may be cases where changed or new installation logic is required, so the possibility of a modified installation library is provided for. • Line 2 provides a short description of the module contents. DR AF • Line 3 specifies that the file exos version is included in the package. This must match the version file at /exos/exos version of the target installation partition. • Line 4 specifies that the file ./bin/sample is to be installed to the /exos partition. • Line 5 specifies that the XML CLI definition file ./config/clidef/sample.xml is to be installed to the exos partition. • Line 6 specifies that the post-installation script /tmp/upgrade is to be executed with the command-line parameter epmrc. The purpose of this is to merge the partial epmrc file included in this package with the full epmrc file that is resident on the switch. Note that the upgrade script and epmrc are included in the *.xmod package implicitly. 2.8 Process Definition File The epmrc file is used by the EXOS process manager (EPM) to control a variety of attributes for the various processes in the system. Some of these attributes include: • Under what conditions the process is allowed to be started. • In what order the process should be started with respect to other processes. • Whether the process is restartable. • Policy for handling process failure. Note that many other process management attributes can be specified through the epmrc file, these are described in detail in <TBD>. The epmrc data for our sample application is contained in sample/src/epmrc.sample as shown in Listing 2.4. Source Code Listings 2.4: Sample epmrc File 1 p r o c=sample : path =./ sample : r e s t a r t =1: s t a r t s e q =1: p r o x i m i t y=l e a f : l i c e n s e=edge : d e s c r= Sample a p p l i c a t i o n : Extreme Networks Confidential 17 2.9. APPLICATION SOURCE CODE CHAPTER 2. CREATING AN EXOS APPLICATION The interpretations of the colon-delimited tokens in this epmrc entry are as follows: 1. proc= identifies the name that should be used to refer to this process (e.g. in CLI commands, log messages, etc.)0. Note that, while this name is usually identical to the executable’s file name, this is not a requirement. 2. path= provides the path to the executable for this process relative to the /exos/bin directory. 3. restart=1 declares that this process may be restarted. 4. startseq=1 declares that this process should be started at boot/initialization along with normal EXOS processes (this parameter should always be set to 1.) T 5. proximity=leaf means that this process is a ”leaf” in the process dependency graph, i.e. no other processes are dependent upon this process. Failed leaf processes are normally just restarted, failed non-leaf processes may require node failover (if a redundant management node is present and in sync) or node restart. 2.9 DR AF 6. license=edge declares that the minimum license requirement for this process to be enabled is ”Edge”. Application Source Code The bulk of our sample application is contained in the C source file sample/src/sample.c, the contents of which are presented in Listing 2.5, Listing 2.6, and Listing 2.7, as described below. Listing 2.5 begins by including several necessary header files: • Line 1 includes "maininc.h", which in turn includes several header files for the most commonly used EXOS APIs. • Line 2 includes "cli subagent.h", needed for the registration of application-specific CLI definitions. • Line 3 includes "sample objdef.h", which is an automatically generated file derived from the sample.obj configuration object definition file. Listing 2.5 continues with the definition of an event handling function for configuration management events. The key elements of this callback function are: • Lines 13-16: when the configuration manager process informs the application that all stored configuration information has been loaded, the application’s process state transitions to ”ready”. • Lines 18-21: in the case where no configuration is loaded (e.g. when the system has been rebooted after the ”unconfigure switch” command has been executed), the application’s process state transitions to ”ready”. • Per lines 23-24, all other configuration management events are ignored. 18 Extreme Networks Confidential CHAPTER 2. CREATING AN EXOS APPLICATION 2.9. APPLICATION SOURCE CODE Source Code Listings 2.5: Configuration Manager Callback for Sample Application DR AF T 1 #include ” maininc . h” 2 #include ” c l i s u b a g e n t . h” 3 #include ” . . / i n c / s a m p l e o b j d e f . h” 4 5 /∗ 6 ∗ C a l l b a c k f u n c t i o n t o h a n d l e c o n f i g u r a t i o n manager c l i e n t e v e n t s . 7 ∗/ 8 s t a t i c int cmBackendEventHandler ( cmBackendEvent e event , void ∗ c o o k i e ) 9 { 10 int r c = CM BACKEND SUCCESS; 11 12 switch ( e v e n t ) { 13 case CM BACKEND EVENT LOAD COMPLETE: 14 /∗ C o n f i g u r a t i o n l o a d i s compl ete , move p r o c e s s s t a t e t o ” r e a d y ” ∗/ 15 e x o s S e t P r o c e s s S t a t e (DM PROCESS STATE READY) ; 16 break ; 17 18 case CM BACKEND EVENT GENERATE DEFAULT: 19 /∗ D e f a u l t c o n f i g u r a t i o n case , move p r o c e s s s t a t e t o ” r e a d y ” ∗/ 20 e x o s S e t P r o c e s s S t a t e (DM PROCESS STATE READY) ; 21 break ; 22 23 default : 24 break ; 25 } 26 return r c ; 27 } Listing 2.6 continues with the definition of an event handler for events from the DM (Device Manager) process. Only the DM MSG LOAD CFG event is handled specially, for this event we simply request our configuration from the configuration manager when directed to do so by DM. Source Code Listings 2.6: Device Manager Callback for Sample Application 29 30 31 32 33 34 35 36 37 38 39 40 41 /∗ ∗ C a l l b a c k f u n c t i o n t o h a n d l e d e v i c e manager c l i e n t e v e n t s . ∗/ s t a t i c void dmHandler ( i p m l P e e r I d t peer , int msg id , int obj , int p1 , void ∗p2 ) { switch ( msg id ) { case DM MSG LOAD CFG: /∗ R e q u e s t c o n f i g u r a t i o n from t h e c o n f i g u r a t i o n manager p r o c e s s ∗/ CM BACKEND REQUEST CONFIG; break ; } } Listing 2.7 contains the bulk or the sample application implementation: • Line 49 initializes the application’s process name from the environment variable that was created when EPM started this process. Extreme Networks Confidential 19 2.9. APPLICATION SOURCE CODE CHAPTER 2. CREATING AN EXOS APPLICATION • Line 52 initializes the DM client library and installs the DM event handler discussed in Listing 2.6. • Line 55 initializes the EPM client library for communication with the EPM process. • Line 58 initializes the application’s process state to BOOTING. • Lines 61-65 initialize the dispatcher library with information about our application. Because our application is single-threaded, most of the parameters passed to dispatchInit() are not relevant. • Line 68 transitions our application’s process state to LOADCFG to inform DM that the application is ready to receive its configuration information. T • Line 71 causes the IPML connection between our application and DM to be initiated, and the DM messaging event handler to be registered with the dispatcher. DR AF • Line 74 initializes the CLI client library, including initiating the IPML connection between this application and the CLI master process and registration of the CLI messaging event handler with the dispatcher. When the IPML connection to the CLI master application is established, the application’s CLI information will be registered with the CLI master process. • Line 77 initializes the configuration management client library, including initiation of the IPML connection to the configuration manager process and registration of the configuration management (CM) event handler. • Line 80 calls dispatchHandler(), which starts the main event-handling loop for our application. Source Code Listings 2.7: Main Application Code for Sample Application 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 /∗ ∗ Main e n t r y p o i n t t o sample EXOS a p p l i c a t i o n . ∗/ int main ( int argc , char ∗∗ argv ) { /∗ I n i t i t i a l i z e p r o c e s s name from environment c r e a t e d by EPM ∗/ exosSetProcessName (NULL) ; /∗ I n i t i a l i z e d e v i c e manager c l i e n t u s i n g dmHandler ( ) c a l l b a c k f u n c t i o n ∗/ dmInit ( 0 , dmHandler ) ; /∗ I n i t i a l i z e EPM c l i e n t ∗/ e p mC l i e n tS e t P id ( ) ; /∗ I n i t i a l i z e EPM c l i e n t ∗/ /∗ I n i t i a l i z e p r o c e s s s t a t e ∗/ e x o s S e t P r o c e s s S t a t e (DM PROCESS STATE BOOTING) ; /∗ I n i t i a l i z e d i s p a t c h e r e v e n t h a n d l e r ∗/ d i s p a t c h I n i t (NULL, /∗ Use d e f a u l t p r o c e s s name ∗/ 0, /∗ Use d e f a u l t k e e p a l i v e i n t e r v a l ∗/ 0, /∗ No c h i l d t h r e a d s ∗/ NULL, /∗ Empty c h i l d t h r e a d a r r a y ∗/ 20 Extreme Networks Confidential CHAPTER 2. CREATING AN EXOS APPLICATION DISPATCH NON THREADED) ; /∗ S i n g l e −t h r e a d e d a p p l i c a t i o n ∗/ /∗ S e t p r o c e s s s t a t e t o l o a d c o n f i g u r a t i o n ∗/ e x o s S e t P r o c e s s S t a t e (DM PROCESS STATE LOADCFG) ; /∗ S t a r t c o n n e c t i o n t o d e v i c e manager ∗/ dmConnect ( ) ; /∗ I n i t i a l i z e CLI c l i e n t l i b r a r y ∗/ c l i S u b a g e n t I n i t ( exosGetProcessName ( ) , NULL) ; /∗ Enter i n f i n i t e e v e n t h a n d l i n g l o o p ∗/ dispatchHandler () ; exit (0) ; } 2.10 T /∗ I n i t i a l i z e c o n f i g u r a t i o n manager c l i e n t l i b r a r y w i t h e v e n t h a n d l e r ∗/ cmBackendInit ( exosGetProcessName ( ) , cmBackendEventHandler ) ; DR AF 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 2.10. MAKEFILE Makefile The file sample/src/Makefile, shown in Listing 2.8, orchestrates the processing of the component source files to produce the output file sample.xmod. At a high level, the interesting components of the Makefile are: • EXOS TOPLEVEL TARGET: Identifies the platform for which this module is targeted; in this case ”cougar” is specified to indicate that the module should be built for for the ”Summit” family of switches. Other supported targets include: – summit rmi - Used when building kernel modules for RMI-based Summit platforms (x460, x480). – aspen msm - BD8800 platform. – i386 - Intel/AMD VM platform. • TARGET BIN: The name of the executable built from source files listed in BIN SRC. • TARGET XMOD: The base name of the installable module generated by this Makefile. • DEFS: Application-specific flags to be used the compiler command-line. • BIN SRC: A list of C source files used to create the application binary. • CLIDEF: The name of the CLI definition file for this module. • OBJDEF: The name of the configuration object definition file for this module. • LIBS: The list of libraries to be used when linking the application binary. Extreme Networks Confidential 21 2.11. APPLICATION VERSION FILE CHAPTER 2. CREATING AN EXOS APPLICATION • INCS: A list of additional directories to be searched for header files. Source Code Listings 2.8: Makefile for Sample Application EXOS TOPLEVEL TARGET = c o u g a r TARGET BIN = sample TARGET XMOD = sample = BIN SRC = sample . c CLIDEF = sample . c l i OBJDEF = sample . o b j LIBS = −l i p m l −lcommon − l c l i −lepm −l e x p a t −l d s −lems −ldm −l s n m p c l i e n t \ −l w k n i n f o −lcmbackend INCS += −I $ (EXOS ROOT) / \ −I . . / i n c T DEFS DR AF 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 include $ (SDKBASE) / e x o s / code / extern xmod . mk include $ (SDKBASE) / e x o s / code / r u l e s . mk 2.11 Application Version File The file sample/src/version, shown in Listing 2.9, is used to generate application versioning information. The numeric version can be displayed via the EXOS CLI command “show process” and is available for run-time checks (e.g. for versioning checks between two instances of a process performing checkpointing) As a side-effect, the presence of a version information file causes build information for debugging to be included in core files produced by the application. The version identifier is not interpreted outside the application, however: • Version components to the left have higher significance than those to the right. • A version containing all zeroes should not be used. Source Code Listings 2.9: Version File for Sample Application 1 2 3 4 2.12 Building and Installation With all source files in place, the procedure for building sample.xmod is simply: 1. export SDKBASE=/path/to/installed/sdk 22 Extreme Networks Confidential CHAPTER 2. CREATING AN EXOS APPLICATION 2.13. OK, I’VE INSTALLED IT... NOW WHAT? 2. make -C sample/src/ The location of the resulting installable module is sample/src/cougar/release/summitX-12.5.1.0-sampl This module can now be downloaded via TFTP and installed on any switch which has the appropriate version of EXOS installed via the download image CLI command. After installation, the run update command can be executed to start the newly-installed application; the application will also be started automatically after a reboot. 2.13 OK, I’ve Installed It... Now What? T While our sample sample application provides no useful functionality yet, there are a number of ways to exercise it from the EXOS CLI to verify that is is present and functioning normally. Some things to try: • restart process "sample" DR AF • show process "sample" • show process "sample" detail • debug epm show process "sample" ipml • debug epm show process "sample" dispatcher • debug ems show trace "sample" info • debug ems show trace "sample" ipml • debug ems show trace "sample" dispatcher 2.14 Looking Forward In the following chapters we will continue to develop our application module, implementing a rudimentary SMTP client to demonstrate a small socket-based application, then continuing to enhance the application by adding CLI commands, non-volatile configuration handling, error/event message capabilities, SNMP MIB support, and more. Extreme Networks Confidential 23 CHAPTER 2. CREATING AN EXOS APPLICATION DR AF T 2.14. LOOKING FORWARD 24 Extreme Networks Confidential Chapter 3 3.1 T Adding Some Functionality Overview DR AF This chapter continues our tutorial development of an EXOS application using the EXOS native application SDK. In this chapter, we implement a small SMTP send-only mail client to serve as a focus around which various aspects of application implementation can be discussed. The goal for this chapter is simply to have the application send an email message one minute after the application has started execution. Some simplifying assumptions include: • The SMTP server address and recipient email address can be fixed at compilation time (the abitility to configure these will be added in a later chapter). • The SMTP server is reachable via an interface belonging to the VR-Mgmt virtual router. 3.2 A Minimal SMTP Client Listing 3.1 contains the source code for a rudimentary SMTP client which is contained insample/src/smtpclien Our goal in this context is not to build a robust, conformant, industrial-strength SMTP client, it is merely to provide an interesting bit of functionality around which to discuss various aspects of the implementation of an EXOS application. Source Code Listings 3.1: Mini SMTP Client Source Code 1 2 3 4 5 6 7 8 9 10 11 12 13 #include #include #include #include #include #include #include #include #include #include <s t d i o . h> <s y s / t y p e s . h> <s y s / s o c k e t . h> <n e t i n e t / i n . h> <netdb . h> < s t d l i b . h> <s t r i n g . h> <u n i s t d . h> ”common/ i n c / e x o s v r . h” ” . . / i n c / s m t p c l i e n t . h” s t a t i c int s e n d a n d e x p e c t ( int fd , char ∗ snd , char ∗ exp ) { 25 3.2. A MINIMAL SMTP CLIENT int r c ; char buf [ 5 1 2 ] ; int s n d l e n = s t r l e n ( snd ) ; int e x p l e n = s t r l e n ( exp ) ; T i f ( sndlen ) { r c = w r i t e ( fd , snd , s n d l e n ) ; i f ( r c != s n d l e n ) return −1; /∗ w r i t e e r r o r ∗/ } i f ( explen ) { r c = r e a d ( fd , buf , s i z e o f buf ) ; i f ( rc < 0) return −1; /∗ rea d e r r o r ∗/ e l s e i f ( r c == s i z e o f buf ) return −1; /∗ r e s p o n s e p o s s i b l y t o o l a r g e ∗/ else i f ( rc < explen ) return −1; /∗ r e s p o n s e t o o s m a l l ∗/ else return strncmp ( buf , exp , e x p l e n ) ? −1 : 0 ; } return 0 ; } DR AF 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 CHAPTER 3. ADDING SOME FUNCTIONALITY int s m t p p o s t ( char ∗ s r v r , char ∗ c l n t , char ∗ s e n d e r , char ∗ r e c i p , char ∗msg ) { int s ; struct s o c k a d d r i n s e r v e r ; struct h o s t e n t ∗hp ; char buf [ 5 1 2 ] ; int r c = −1; int v r i d = MGMT VR ID ; s = s o c k e t (AF INET , SOCK STREAM, 0 ) ; i f ( s < 0) return −1; i f ( s e t s o c k o p t ( s , SOL SOCKET, SO VRID , &v r i d , s i z e o f v r i d ) < 0 ) return −1; s e r v e r . s i n f a m i l y = AF INET ; r c = −2; hp = gethostbyname ( s r v r ) ; i f ( hp == NULL) goto out ; memcpy(& s e r v e r . s i n a d d r , hp−>h addr , hp−>h l e n g t h ) ; s e r v e r . s i n p o r t = htons (25) ; r c = −3; i f ( c o n n e c t ( s , ( struct s o c k a d d r ∗ )&s e r v e r , s i z e o f s e r v e r ) < 0 ) goto out ; 26 Extreme Networks Confidential CHAPTER 3. ADDING SOME FUNCTIONALITY r c = −4; i f ( s e n d a n d e x p e c t ( s , ” ” , ” 220 ” ) ) goto out ; s n p r i n t f ( buf , s i z e o f buf , ”HELO %s \ r \n” , c l n t ) ; i f ( s e n d a n d e x p e c t ( s , buf , ” 250 ” ) ) goto out ; s n p r i n t f ( buf , s i z e o f buf , ”MAIL From:% s \ r \n” , s e n d e r ) ; i f ( s e n d a n d e x p e c t ( s , buf , ” 250 ” ) ) goto out ; i f ( s e n d a n d e x p e c t ( s , ”DATA\ r \n” , ” 354 ” ) ) goto out ; i f ( s e n d a n d e x p e c t ( s , msg , ” ” ) ) goto out ; T s n p r i n t f ( buf , s i z e o f buf , ”RCPT To:% s \ r \n” , r e c i p ) ; i f ( s e n d a n d e x p e c t ( s , buf , ” 250 ” ) ) goto out ; DR AF 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 3.2. A MINIMAL SMTP CLIENT i f ( s e n d a n d e x p e c t ( s , ” \ r \n . \ r \n” , ” 250 ” ) ) goto out ; i f ( s e n d a n d e x p e c t ( s , ”QUIT\ r \n” , ” 221 ” ) ) goto out ; rc = 0; out : close ( s ) ; return r c ; } The external interface to smtpclient.c will go in sample/inc/smtpcli.h, as shown in Listing 3.2. Source Code Listings 3.2: Mini SMTP Client Header File 1 int s m t p p o s t ( char ∗ s r v r , char ∗ c l n t , char ∗ s e n d e r , char ∗ r e c i p , char ∗msg ) ; Note that the code in Listing 3.1 is not written in the event-driven paradigm that should be used in EXOS applications; specifically, the connect(), write(), and read() system calls can block for extended periods of time. We will tolerate this model for the moment, this ssue will be revisted later in this chapter when the consequences of this implemenation and ways to address them are considered. We now have the means for sending an email message via SMTP, but we still need to be able to send the the message at some time after our application starts. For this, we will use the dispatcher timer facility as discussed in the next section of this chapter. Extreme Networks Confidential 27 3.3. DISPATCHER TIMERS 3.3 CHAPTER 3. ADDING SOME FUNCTIONALITY Dispatcher Timers As discussed in Section 2.3 or Chapter 2, the core event-handling loop of an EXOS application is implemented in the dispatcher library. The dispatcher library includes facilities for creating timers, which have the following properties: • The minimum granularity of a dispatcher timer is 50 milliseconds. • The maximum timeout of a dispatcher timer is 232 − 1 seconds (about 136 years). • A dispatcher timer can repeat periodically (cyclic) or fire only once (one-shot). • On expiration, a call is made to a user-provided callback function. T The API function for creating a dispatcher timer is shown in Listing 3.3. The parameters to this function include: • A pointer to the user-provided callback function of type dispatchWork f. DR AF • Two argument values to be passed to the callback function of type void *. • A relative timeout specified as a struct timeval *. • The type of the timer, either DISPATCH TM TYPE ONESHOT or DISPATCH TM TYPE CYCLIC. Source Code Listings 3.3: Prototype for dispatchExecuteWorkItem() typedef void ( d i s p a t c h W o r k f ) ( void ∗ arg1 , void ∗ a r g 2 ) ; d i s p a t c h W o r k t ∗ dispatchExecuteWorkItem ( d i s p a t c h W o r k f void void struct t i m e v a l int 3.4 func , ∗ arg1 , ∗ arg2 , ∗ timeout , type ) ; Putting it All Together With an SMTP client and the ability to set a dispatcher timer in hand, it’s time to return our goals for the application for this chapter. First we need to modify sample/src/Makefile to add smtpclient.c to BIN SRC as shown in Listing 3.4. Source Code Listings 3.4: Makefile Modifications BIN SRC = sample . c \ smtpclient . c Next we make the additions to sample/src/sample.c shown in Listing 3.5: 28 Extreme Networks Confidential CHAPTER 3. ADDING SOME FUNCTIONALITY 3.5. THE EMS TRACE FACILITY 1. Include smtpclient.h header file. 2. Define timer callback function sampleSendMailCB. 3. Add call to dispatchExecuteWorkItem() to create timer, just before entering dispatchHandler(). Source Code Listings 3.5: Modifications to sample.c /∗ −−− s n i p −−− ∗/ #include ” . . / i n c / s m t p c l i e n t . h” /∗ −−− s n i p −−− ∗/ DR AF T s t a t i c void sampleSendMailCB ( void ∗ arg1 , void ∗ a r g 2 ) { smtp post ( ” 1 0 . 5 . 2 . 1 5 8 ” , /∗ Modify f o r your environment ∗/ ” 10.66.4.10 ” , ” someone@somecorp . com” , ” l r i c h a r d s o n @ S y z y g y −HLR” , /∗ Modify f o r your environment ∗/ ” H e l l o , world ! \ n” ) ; } /∗ −−− s n i p −−− ∗/ timeout . t v s e c = 60; timeout . t v u s e c = 0 ; dispatchExecuteWorkItem ( sampleSendMailCB , NULL, NULL, &timeout , DISPATCH TM TYPE ONESHOT) ; /∗ −−− s n i p −−− ∗/ At this point we can rebuild the sample XMOD by executing ”make -C sample/src". Assuming the specified SMTP server is reachable, the recipient is accepted, and the SMTP message is otherwise well-formed, our ”Hello, world!” email message should be received after installing the updated XMOD and rebooting. What if our email message is never received? At this point we might verify connectivity between the switch and the SMTP server (e.g. by "telnet vr vr-mgmt <ip-address> 25" from the switch), but assuming connectivity is confirmed, how can we get insight into what’s happening in the application? 3.5 The EMS Trace Facility The EMS Trace facility provides the ability to create and manage in-memory trace buffers for developer-level debugging tasks. Messages in these trace buffers are logged with a timestamp and a global sequence number that is unique across all trace buffers within a single application. The buffers are fixed in size, with the size being configured when the trace buffer is created, and are treated as circular buffers. Extreme Networks Confidential 29 3.5. THE EMS TRACE FACILITY CHAPTER 3. ADDING SOME FUNCTIONALITY The two key APIs for using EMS trace buffers are emsInitTraceBuffer(), which creates a trace buffer, and emsTraceLogf(), which logs messages into a buffer using printf-style formatting. The prototypes for these functions are shown in Listing 3.6. Source Code Listings 3.6: EMS Tracing API void ∗ e m s I n i t T r a c e B u f f e r ( char ∗name , u i n t 3 2 t s i z e , emsTraceFormat f ∗ emsTraceFormatCallBack ) ; void emsTraceLogf ( void ∗ t r a c e H a n d l e , int type , char ∗ fmt , . . . ) ; T Adding an EMS trace buffer to our application and using it is straightforward, we simply introduce a global variable to contain the trace buffer handle and add a call to emsInitTraceBuffer() as shown in the code fragments of Figure 3.7. Source Code Listings 3.7: Creating an EMS Trace Buffer DR AF void ∗ d e b u g h a n d l e=NULL; /∗ C r e a t e an 8 KB t r a c e b u f f e r ∗/ d e b u g h a n d l e = e m s I n i t T r a c e B u f f e r ( ” debug ” , 8 1 9 2 , NULL) ; Then, we’ll add a few trace messages: Source Code Listings 3.8: Using an EMS Trace Buffer /∗ In main ( ) , b e f o r e d i s p a t c h H a n d l e r ( ) ∗? emsTraceLogf ( d e b u g h a n d l e , 0 , ” C a l l i n g d i s p a t c h H a n d l e r ( ) ”) ; /∗ In sampleSendMailCB ( ) , b e f o r e c a l l i n g s m t p p o s t ( ) ∗/ emsTraceLogf ( debug handle , 0 , ” Entered sampleSendMailCB ” ) ; /∗ In sampleSendMailCB ( ) , a f t e r c a l l i n g s m t p p o s t ( ) ∗/ emsTraceLogf ( debug handle , 0 , ” s m t p p o s t ( ) r e t u r n e d %d” , r c ) ; After changing the SMTP server IP address to an unreachable address, rebuilding, and installing, we can now execute the command debug ems show trace "sample" debug on the switch and see: Source Code Listings 3.9: Formatted Output from an EMS Trace Buffer 04/28/2010 1 6 : 3 0 : 3 6 . 6 6 4 3 7 2 [ 1 4 ] <sample : debug> C a l l i n g d i s p a t c h H a n d l e r ( ) 04/28/2010 1 6 : 3 1 : 3 6 . 7 0 0 5 5 0 [ 1 7 3 ] <sample : debug> Entered sampleSendMailCB ( ) 04/28/2010 1 6 : 3 1 : 4 0 . 0 3 7 3 1 3 [ 1 7 4 ] <sample : debug> s m t p p o s t ( ) r e t u r n e d −3 From which we can glean: • The dispatcher timer callback was, in fact, called 60 seconds after being created. • The call to smtp post() failed with return code -3, which according to smtpclient.c means that the call to connect() failed. 30 Extreme Networks Confidential CHAPTER 3. ADDING SOME FUNCTIONALITY 3.6 3.6. NON-BLOCKING SOCKETS Non-Blocking Sockets DR AF T TBD... implement smtp post() using dispatchAddFileRW() API and state machine. Extreme Networks Confidential 31 CHAPTER 3. ADDING SOME FUNCTIONALITY DR AF T 3.6. NON-BLOCKING SOCKETS 32 Extreme Networks Confidential Chapter 4 4.1 T CLI and Configuration Overview 4.2 DR AF In this chapter we continue the development of an EXOS application by adding support for configuration via the command-line interface, and for storing the configuration information in the persistent configuration database. EXOS CLI Architecture As shown in the diagram in Figure 4.1, EXOS applications receive configuration requests and produce responses to configuration requests in the form of XML-formatted messages. For a given configuration transaction, an EXOS application acts either as a configuration management front-end or conifguration management back-end. As might be expected, front-ends generate configuration requests and back-ends service configuration requests. Note that these roles are not mutually exclusive; a front-end application will generally have some configurable attributes, and therefore needs to act as a back-end as well. All configuration requests and responses are routed through the configuration manager process, which is responsible for: • Routing requests to the appropriate back-end application instance. • Routing responses to the appropriate front-end application. • Serializing configuration request execution to ensure that only one configuration operation for an application is active at any given time. • For systems with redundant managment nodes, ensuring that each configuration operation is synchronized between the current master node and any backup nodes. 33 CHAPTER 4. CLI AND CONFIGURATION DR AF T 4.2. EXOS CLI ARCHITECTURE Figure 4.1: Configuration Message Flow The main elements required to implement CLI and configuration management functionality in an EXOS application include: 1. A configuration object definition file that defines, in C-like data structure syntax, the following items: • • • • One or more configuration objects. The data type and name for the member fields supported for each object. Which configuration actions (get, set, or setop) are implemented for each object. Whether the object is to be included in persistent configuration storage and if so, the relative order each object type is to be set at configuration load time. 2. Files generated from the configuration object definition file by the object2c.pl utility, including: 34 Extreme Networks Confidential CHAPTER 4. CLI AND CONFIGURATION 4.3. DEFINING CONFIGURATION OBJECTS • * cmobj.h and * objdef.h, header files containing C language structure definitions and utility macros for working with configuration objects. • * cmobj.c and * objdef.c, source files containing functions for working with configuration objects (including transformations between XML and C forms). • *.dtd, an XML “Document Type Definition” for the configuration objects, methods, and fields. 3. C functions written by the application developer as required to implement configuration management actions (set, get, or setop) for each object type. T 4. A CLI definition file specifying the syntax for each CLI command, usually also containing TCL code for each command. The subsequent sections of this chapter detail the implementation of support for the following CLI commands: DR AF • configure sample smtp-server <smtp server> • configure sample email <email address> • show sample configuration 4.3 Defining Configuration Objects In order to implement persistent storage of configuration information, we must provide definitions for the configuration objects that will be used to represent this information. We start by identifying the required configuration elements. For simplicity, we will assume that only one destination is required and therefore include both the SMTP server address and the email address of the recipient in a single configuration object. (Note that a “real” implementation would likely need to separate server configuration from the email address list.) With this information in hand, we can update the previously created sample/src/sample.obj file as shown in Listing 4.1 Source Code Listings 4.1: Configuration Object Definition File 1 2 3 4 5 6 7 8 9 struct s a m p l e d e s t i n a t i o n t { char s m t p s e r v e r [ 6 4 ] ; char r e c i p i e n t [ 6 4 ] ; saveorder 1; method g e t ; method s e t ; } sample destination ; • Line 1 of Listing 4.1 begins the definition of a configuration object structure named “sample destination”. This name will be used in C language definitions as well as XML tags. Extreme Networks Confidential 35 4.4. GET/SET METHOD SUPPORT CHAPTER 4. CLI AND CONFIGURATION • Line 2 specifies a string field named “smtp server” to contain the host name or IP address of the SMTP server. • Line 3 specifies a string field named “recipient” to contain the email address to which our email messages will be sent. • Line 5 specifies two things: (1) that this configuration object should be saved with the persistent system configuration, and (2) that this object should be saved and loaded first with respect to other configuration objects in this module. • Line 7 declares that the “get” method is supported for this object. • Line 8 declares that the “set” method is supported for this object. 4.4 DR AF T If we now attempt to rebuild our application, we will discover that the link step fails due to having two unresolved symbols: sample destination t get() and sample destination t set(). This is a consequence of having declared in sample.obj that the sample destination object supports the “get” and “set” methods. It is now up to us to implement them. Get/Set Method Support The code implementing the functions for the requisite “get” and“set” methods is contained in a a new file, which will be located at sample/src/sample cli.c. The contents of this file are shown in Listing 4.2, Listing 4.3, and Listing 4.4. Listing 4.2 begins by including several necessary header files. Note that sample objdef.h is one of the files created automatically from sample.obj. On line 5 we declare a global structure to store configuration state locally. In this case we are using the structure definition for the configuration object, although this is not requirement. Source Code Listings 4.2: Preamble for Get and Set Method Implementation 1 #include ” maininc . h” 2 #include ” c l i s u b a g e n t . h” 3 #include ” . . / i n c / s a m p l e o b j d e f . h” 4 5 sample destination t globalConfig = {{0}}; Listing 4.3 contains the definition of the “get” method, outlined as follows: • Line 7 defines the function to return an integer (which will be either CM BACKEND ERROR or CM BACKEND SUCCESS in this case) and take two parameters: a back-end context pointer which is used to specify and track the response, and a pointer to a sample destination t structure which contains any configuration object fields from the request message. • At line 11 we allocate an object structure which will be sent in XML form to the requester. • Because the newly allocated object contains no valid fields, at line 15 we mark all fields in the object as invalid. 36 Extreme Networks Confidential CHAPTER 4. CLI AND CONFIGURATION 4.4. GET/SET METHOD SUPPORT • In lines 17-19 we copy our local email recipient string to the object and mark the corresponding object field as valid. • In lines 21-23 we copy our local SMTP server string to the object and mark the corresponding object field as valid. • At line 25 the response object is attached to the backend context structure to be used in forming the XML response message. Note that the memory allocated for the object will be freed by the caller. T • Lastly, at line 27 we return CM BACKEND SUCCESS. Upon returning from this function, the object will be converted to XML form and sent to the configuration manager, which will then forward it to the original requester. Source Code Listings 4.3: Get Method Implementation 22 23 24 25 26 27 28 int s a m p l e d e s t i n a t i o n t g e t ( cmBackendContext t ∗ ctx , s a m p l e d e s t i n a t i o n t ∗ i n ) { s a m p l e d e s t i n a t i o n t ∗ o b j = NULL; DR AF 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 i f ( ( o b j = s a m p l e d e s t i n a t i o n t a l l o c ( ) ) == NULL) { cmBackendMessage ( ctx , ” I n t e r n a l e r r o r : m a l l o c ( ) f a i l e d . \ n” ) ; return CM BACKEND ERROR; } SAMPLE DESTINATION T SET ZERO VALID( o b j ) ; s t r n c p y ( obj−>r e c i p i e n t , g l o b a l C o n f i g . r e c i p i e n t , s i z e o f obj−>r e c i p i e n t − 1 ) ; obj−>r e c i p i e n t [ s i z e o f obj−>r e c i p i e n t − 1 ] = ’ \0 ’ ; SAMPLE DESTINATION T SET VALID( obj , r e c i p i e n t ) ; s t r n c p y ( obj−>s m t p s e r v e r , g l o b a l C o n f i g . s m t p s e r v e r , s i z e o f obj−>s m t p s e r v e r − 1 ) ; obj−>s m t p s e r v e r [ s i z e o f obj−>s m t p s e r v e r − 1 ] = ’ \0 ’ ; SAMPLE DESTINATION T SET VALID( obj , s m t p s e r v e r ) ; SAMPLE DESTINATION T SET OUTPUT( ctx , o b j ) ; return CM BACKEND SUCCESS; } Listing 4.4 contains the definition of the “set” method, implemented as follows: • Line 30 defines the function to return an integer (which will be CM BACKEND SUCCESS in this case) and take two parameters: a back-end context pointer which is used to control the contents of the reqponse, and a pointer to a sample destination t structure initialized from the XML set request. • Line 32 checks whether the recipient field is valid, which will be true if the field was present in the XML request. If so, the field is copied to the global configuration structure in lines 33-35. Extreme Networks Confidential 37 4.5. CLI DEFINITION FILE CHAPTER 4. CLI AND CONFIGURATION • Line 38 checks whether the smtp server field is valid, which will be true if the field was present in the XML request. If so, the field is copied to the global configuration structure in lines 39-41. • Finally, we return CM BACKEND SUCCESS at line 44 to indicate that the operation completed successfully. Source Code Listings 4.4: Set Method Implementation T int s a m p l e d e s t i n a t i o n t s e t ( cmBackendContext t ∗ ctx , s a m p l e d e s t i n a t i o n t ∗ i n ) { i f ( SAMPLE DESTINATION T IS VALID( in , r e c i p i e n t ) ) { strncpy ( globalConfig . recipient , in−>r e c i p i e n t , sizeof globalConfig . r e c i p i e n t − 1) ; } i f ( SAMPLE DESTINATION T IS VALID( in , s m t p s e r v e r ) ) { strncpy ( globalConfig . smtp server , in−>s m t p s e r v e r , sizeof globalConfig . smtp server − 1) ; } DR AF 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 return CM BACKEND SUCCESS; } 4.5 CLI Definition File Listing 4.5 contains the definition for the first CLI command to be implemented, outlined as follows: • Line 1 declares the CLI style for this set of commands, in this case indicating that the enclosed commands are in the standard Extreme CLI style. The %style directive is terminated on line 59 of Listing 4.6. • Line 2 defines the command syntax. In command syntax definitions, square brackets indicate a set of alternatives that are separated by the vertical bar or “pipe” character, keywords are verbatim, and identifiers enclosed in < and > are parameters. Therefore, this command definition matches either of the following two CLI commands: configure sample smtp-server <smtp server> configure sample email <email address> • Lines 3-9 define various attributes for tokens in the command definition, including: – help: Help text to display for this token, e.g. when the CLI user types TAB or ’ ?’ while entering a command. Applies to both keywords and parameters. 38 Extreme Networks Confidential CHAPTER 4. CLI AND CONFIGURATION 4.5. CLI DEFINITION FILE – type: For parameters, specifies the type of the parameter. Only “string” is used here, but various other types are available, including a range of integral types, IP addresses, and MAC addresses. – range: For parameters, specifies the range of values (for integral types) or maximum string length (for the “string” type). • Line 11 specifies that this command is handled via the XML interface to the configuration manager, in which case the enclosed statements are to be interpreted as TCL code for handling the XML request/response and formatting the result for the user. • Lines 12-31 contain the TCL code for this command action, as follows: T – Line 12 takes the command tokens (entered by the user) and creates an array that can be indexed by keyword or parameter name. – Line 14 initializess the local variable“xml” opening XML tag identifying the configuration object to which the request should be applied. DR AF – Lines 16-18 check for the existence of the “smtp-server” keyword in the entered command and, if present, adds the “<smtp server>00 value to the XML string. – Lines 19-21 check for the existence of the “email” keyword in the entered command and, if present, adds the“<email address>” value to the XML string. – Line 22 adds the closing tag for the configuration object name corresponding to the tag opened on line 13. – Line 24 sends the fully-formed XML request for module “sample” to the configuration manager and waits for the response by invoking the “setone” built-in function, then assigns the XML result to the “reply” variable. – Line 25 creates an array from the XML result string for simplified access to elements in the response. – Lines 27-29 check for an error result and, if an error occurred during the processing of the request, the associated message is displayed. – Line 31 “unsets” all local variables to remove their names from the global namespace and to free memory allocated for them. Source Code Listings 4.5: TCL Definition for “configure” Command 1 %s t y l e = ” extreme ”% 2 %command=” c o n f i g u r e sample [ smtp−server <s m t p s e r v e r > | e m a i l <e m a i l a d d r e s s >]”% 3 %a t t r i b u t e% 4 %sample => help= ” sample a p p l i c a t i o n ”;% 5 %smtp−server => help= ”SMTP m a i l s e r v e r IP a d d r e s s o r hostname ”;% 6 %<s m t p s e r v e r > => help= ”SMTP S e r v e r ” ; type= ” s t r i n g ” ; range= ” [ 0 , 6 3 ] ”;% 7 %e m a i l => help= ” Email a d d r e s s o f r e c i p i e n t ”;% 8 %<e m a i l a d d r e s s > => help= ” Email a d d r e s s ” ; type= ” s t r i n g ” ; range= ” [ 0 , 6 3 ] ”;% 9 %e n d a t t r i b u t e% 10 11 %action= ”xml”% Extreme Networks Confidential 39 4.5. CLI DEFINITION FILE CHAPTER 4. CLI AND CONFIGURATION DR AF T 12 array set a r g s $argv 13 14 set xml ”<s a m p l e d e s t i n a t i o n >” 15 16 i f [ i n f o e x i s t s a r g s ( smtp−server ) ] { 17 append xml ”<s m t p s e r v e r >$ a r g s (< s m t p s e r v e r >)</s m t p s e r v e r >” 18 } 19 i f [ info exists args ( email ) ] { 20 append xml ”<r e c i p i e n t >$ a r g s (< e m a i l a d d r e s s >)</ r e c i p i e n t >” 21 } 22 append xml ”</ s a m p l e d e s t i n a t i o n >” 23 24 set r e p l y [ s e t o n e ” sample ” $xml ] 25 b u i l d a r r a y $ r e p l y −indexed 26 27 i f { [ string e q u a l $xmlData ( r e p l y . 0 . s t a t u s . 0 ) {ERROR} ] } { 28 show ” $xmlData ( r e p l y . 0 . m e s s a g e . 0 ) \n” 29 } 30 31 unset a r g s xml r e p l y 32 %e n d a c t i o n% 33 %endcommand% Listing 4.6 contains the definition for the show sample configuration command, outlined as follows: • Line 35 declares the command syntax, which in this case consists only of keyword tokens. • Lines 36-39 specify help text attributes for each command token (excluding the first-level token show, for which help text is defined elsewhere.) • Lines 42-57 contain the TCL code for this command’s action: – Line 44 initializes the XML string to identify the configuration object we will be performing a“get” operation on. Note that the equivalent short-hand notation <sample destination/> could also be used here. – Line 46 causes a get request to be sent to the “sample” application by invoking the“getone” function. The response to the request is assigned to the “reply” variable. – Line 47 parses the XML response into an array for simplified access. – Lines 49 ensures that the “get” operation was successful, and if so proceeds to display the response. – Lines 50 and 51 assign the SMTP server and email address strings to variables for convenience. – Lines 53-54 format and display the configuration information for a terminal session. – Line 57 “unsets” all local variables to remove their names from the global namespace and to free memory allocated for them. 40 Extreme Networks Confidential CHAPTER 4. CLI AND CONFIGURATION 4.5. CLI DEFINITION FILE Source Code Listings 4.6: TCL Definition for“show” Command DR AF T 35 %command=”show sample c o n f i g u r a t i o n ”% 36 %a t t r i b u t e% 37 %sample => help= ” sample a p p l i c a t i o n ”;% 38 %c o n f i g u r a t i o n => help= ” c o n f i g u r a t i o n data ”;% 39 %e n d a t t r i b u t e% 40 41 %action= ”xml”% 42 array set a r g s $argv 43 44 set xml ”<s a m p l e d e s t i n a t i o n ></s a m p l e d e s t i n a t i o n >” 45 46 set r e p l y [ g e t o n e ” sample ” $xml ] 47 b u i l d a r r a y $ r e p l y −indexed 48 49 i f { ! [ string e q u a l $xmlData ( r e p l y . 0 . s t a t u s . 0 ) ERROR] } { 50 set s e r v e r $xmlData ( r e p l y . 0 . m e s s a g e . 0 . s a m p l e d e s t i n a t i o n . 0 . s m t p s e r v e r . 0 ) 51 set a d d r e s s $xmlData ( r e p l y . 0 . m e s s a g e . 0 . s a m p l e d e s t i n a t i o n . 0 . r e c i p i e n t . 0 ) 52 53 show [ format ” SMTP S e r v e r : %−32s\n” $ s e r v e r ] 54 show [ format ” Email A d d r e s s : %−32s\n” $ a d d r e s s ] 55 } 56 57 unset a r g s xml r e p l y s e r v e r a d d r e s s 58 %e n d a c t i o n% 59 %endcommand% 60 %e n d s t y l e% Extreme Networks Confidential 41 CHAPTER 4. CLI AND CONFIGURATION DR AF T 4.5. CLI DEFINITION FILE 42 Extreme Networks Confidential Chapter 5 5.1 T Adding EMS Support Overview 5.2 DR AF The Event Management System (EMS) provides a flexible infrastructure for defining, using, and publishing event messages on a per-application basis with centralized run-time facilities for controlling and monitoring the logging of event messages throughout the system. In this chapter we continue to enhance the tutorial EXOS application by adding support for event log messaging using the EMS infrastructure. EXOS EMS Architecture Placeholder for a brief description of the EMS server application, client library, and features/capabilities. 5.3 Event Definition File Naming EMS event definition files reside in the src/ems subdirectory. There may be multiple EMS event definition files for a given EXOS application, generally a single file for the overall application and some number of event definition files (possibly zero) for the application’s sub-components. The naming convention for EMS event definition files for the overall application is: <application-name> ems.xml According to these requirements, our EMS event definition file should be located at: src/ems/sample ems.xml. 5.4 Event Definition File Content We will create the XML-formatted event definition file using the GUI emsEdit.pl utility. Required information (beyond individual event information) includes: 43 5.4. EVENT DEFINITION FILE CONTENT CHAPTER 5. ADDING EMS SUPPORT 1. Component Name: This is generally the same as the application binary name, which in our case will be ”sample”. 2. Default Severity Threshold: This is the minimum message severity to be displayed by default, which we will set to be Info. 3. Component Description: This is a short description of the application. With this information in hand, and after creating the subdirectory sample/src/ems, we start the GUI event definition tool by invoking: $SDKBASE/tools/xml2ems/emsEdit.pl sample/src/ems/sample ems.xml DR AF T which should result in the display of a panel similar to the one in Figure 5.1. Figure 5.1: EMS Event Editor Initial Screen 44 Extreme Networks Confidential CHAPTER 5. ADDING EMS SUPPORT 5.4. EVENT DEFINITION FILE CONTENT Data entry for the global component information is as follows: 1. Clear the contents of the text box to the right of Component Info and enter sample. T 2. Click in the next box to the right (which initially reads Error), and select Info to set the default severity threshold. DR AF 3. Clear the contents of the right-most text box in the first row (which initially reads Subsystem description), and enter A sample EXOS application as the component description. We are now ready to define an EMS event, the purpose of which is to log a successful attempt to send an email message by our application. We need the following bits of information: • Condition Mnemonic: A short name for the event, up to 15 characters in length. We’ll use EMailSent. • Condition Severity: Info. • Message Text: We’ll use ”Sent email message to %address% via %server%.”. Parameters %address% and %server% will have type ”String”. Entering this information should give results similar to Figure 5.2. We can now click on Save and New for entry of information for our second event definition. Extreme Networks Confidential 45 CHAPTER 5. ADDING EMS SUPPORT DR AF T 5.4. EVENT DEFINITION FILE CONTENT Figure 5.2: EMS Event Editor with First Event Information We are now ready to define our second EMS event, the purpose of which is to log an unsuccessful attempt to send an email message by our application, which we’ll define as follows: • Condition Mnemonic: EMailSendFailed. • Condition Severity: Error. • Message Text: We’ll use ”Email send to %address% via %server% failed (%reason%.”. All three parameters will have type ”String”. Entering this information should give results similar to Figure 5.3. We can now click on Save and Exit to produce the XML definitions for these events as shown in Listing 5.1. 46 Extreme Networks Confidential 5.4. EVENT DEFINITION FILE CONTENT DR AF T CHAPTER 5. ADDING EMS SUPPORT Figure 5.3: EMS Event Editor with Second Event Information Source Code Listings 5.1: XML Definitions for EMS Events 1 2 3 4 5 6 7 8 <?xml version=” 1 . 0 ” e n c o d i n g=”UTF−8” ?> < !−− L a s t e d i t e d w i t h e x o s / t o o l s / xml2ems / emsEdit . p l on 05/03/2010 15 : 4 5 : 1 8 −−> < !DOCTYPE Component SYSTEM ” . . / . . / . . / . . / system /ems/ i n c / ems component . dtd ”> <Component Name=” sample ” F a c t o r y T h r e s h o l d=” I n f o ” T i t l e=”A sample EXOS a p p l i c a t i o n . ” DocTypeVersion=” 4 ” FormatVersion=” 2 ” C o n t e n t V e r s i o n=” 1 ” Copyright=” Copyright ( c ) 2002 −2009 by Extreme Networks I n c . ”> <RCS Author=” $ Author $ ” Date=” $ Date $ ” F i l e=” $ RCSFile $ ” S o u r c e=” $ S o u r c e $ ” R e v i s i o n=” $ R e v i s i o n $ ”> <Log> </Log> </RCS> <S e v e r i t y U s e C r i t i c a l U s e=” C r i t i c a l ” ErrorUse=” E r r o r ” WarningUse=”Warning” N o t i c e U s e=” N o t i c e ” I n f o U s e=” I n f o ” DebugSummaryUse=”DebugSummary” Extreme Networks Confidential 47 5.5. MAKEFILE CHANGES 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 T 10 11 12 DebugVerboseUse=” DebugVerbose ” DebugDataUse=”DebugData” /> <C o n d i t i o n Mnemonic=”DebugSummary” S e v e r i t y=”Debug−Summary” Index=” 0 ” ReviewState= ”New”> <Message>< ! [CDATA[% format%] ]></ Message> <Parameter Name=” format ” Type=” P r i n t f ” /> <Comment>< ! [CDATA[ This i s a g e n e r i c Debugging summary i n f o r m a t i o n S e v e r i t y C o n d i t i o n ] ]></Comment> <D e s c r i p t i o n>< ! [CDATA[A c o n d i t i o n has been d e t e c t e d t h a t may i n t e r e s t a developer determining the r e a s o n u n d e r l y i n g some system b e h a v i o r . The c i r c u m s t a n c e s may be e i t h e r v e r y common o r c o m p l e t e l y unexpected , but t h e i n f o r m a t i o n p r o v i d e d i n t h e a s s o c i a t e d message i s such t h a t t h e i n t e r n a l w o r k i n g s o f t h e system a r e exposed . ] ]></ D e s c r i p t i o n> <Remedy>< ! [CDATA[ There i s no remedy b e c a u s e t h e r e i s no problem t o be r e s o l v e d . ] ]></Remedy> <Author>l r i c h a r d s o n</ Author> </ C o n d i t i o n> <C o n d i t i o n Mnemonic=” DebugVerbose ” S e v e r i t y=”Debug−Verbose ” Index=” 1 ” ReviewState= ”New”> <Message>< ! [CDATA[% format%] ]></ Message> <Parameter Name=” format ” Type=” P r i n t f ” /> <Comment>< ! [CDATA[ This i s a g e n e r i c Debugging v e r b o s e i n f o r m a t i o n S e v e r i t y C o n d i t i o n ] ]></Comment> <D e s c r i p t i o n>< ! [CDATA[A c o n d i t i o n has been d e t e c t e d t h a t may i n t e r e s t a d e v e l o p e r a n a l y z i n g some system b e h a v i o r a t a more v e r b o s e l e v e l than p r o v i d e d by t h e debug summary i n f o r m a t i o n . ] ]></ D e s c r i p t i o n> <Remedy>< ! [CDATA[ There i s no remedy b e c a u s e t h e r e i s no problem t o be r e s o l v e d . ] ]></Remedy> <Author>l r i c h a r d s o n</ Author> </ C o n d i t i o n> <C o n d i t i o n Mnemonic=” EMailSent ” S e v e r i t y=” I n f o ” Index=” 2 ” ReviewState=”New”> <Message>< ! [CDATA[ Sent e m a i l message t o %a d d r e s s% v i a %s e r v e r %. ] ]></ Message> <Parameter Name=” a d d r e s s ” Type=” S t r i n g ” /> DR AF 9 CHAPTER 5. ADDING EMS SUPPORT 5.5 Makefile Changes Two small changes must be made to our Makefile before the C API files will be generated from our newly-added event definition file. First, we need to add ems/sample ems dcl.c to BIN DIRS as shown in Figure 5.2. Source Code Listings 5.2: First Makefile Modification (Add Generated Source File) BIN SRC = sample . c \ smtpclient . c \ sample cli . c \ ems/ s a m p l e e m s d c l . c Second, we need to define the constant EMS sample COMPONENT, which would normally be added to the list of components in $SDKBASE/code/system/ems/inc/ems components.h. Since we are building an application outside the base EXOS build process, we will provide this definition on 48 Extreme Networks Confidential CHAPTER 5. ADDING EMS SUPPORT 5.6. SOURCE CODE CHANGES the compiler command-line as shown in Figure 5.3, taking the last enumeration constant listed in $SDKBASE/code/system/ems/inc/ems components.h, which happens to be EMS Kern MPLS COMPONENT in this case. (Note: we really need a better mechanism for this.) Source Code Listings 5.3: Second Makefile Modification (Define EMS Component) = −D EMS sample COMPONENT=\( EMS Kern MPLS COMPONENT+1\) DEFS We can now execute make -C sample/src and see a number of new files that have been generated from from the event definition XML, including: T • sample/src/ems/sample ems dcl.c: Implementation of event logging C API for ”sample” application. • sample/inc/ems/sample ems api.h: EMS API definitions for the ”sample” application. 5.6 DR AF • sample/inc/ems/sample ems dcl.h: EMS API definitions for the ”sample” application. Source Code Changes To enable EMS event logging in our application, we need to make two modifications to sample/src/sample.c. First, we need to include the API definitions file sample ems api.h as shown in Figure 5.4. Source Code Listings 5.4: Including sample ems api.h #include #include #include #include #include ” maininc . h” ” s a m p l e o b j d e f . h” ” c l i s u b a g e n t . h” ” . . / i n c / s m t p c l i . h” ” . . / i n c /ems/ s a m p l e e m s a p i . h” Second, we need to initialize the EMS library; this should be done after the dispatcher library has been initialized and before the main dispatcher loop is entered, as shown in Figure 5.5. Source Code Listings 5.5: Initializing EMS client library /∗ −−− s n i p −−− ∗/ /∗ I n i t i a l i z e d i s p a t c h e r e v e n t h a n d l e r ∗/ d i s p a t c h I n i t (NULL, /∗ Use d e f a u l t p r o c e s s name ∗/ 0, /∗ Use d e f a u l t k e e p a l i v e i n t e r v a l ∗/ 0, /∗ No c h i l d t h r e a d s ∗/ NULL, /∗ Empty c h i l d t h r e a d a r r a y ∗/ DISPATCH NON THREADED) ; /∗ S i n g l e −t h r e a d e d a p p l i c a t i o n ∗/ /∗ I n i t i a l i z e EMS c l i e n t l i b r a r y ∗/ EMS REGISTER sample ( ) ; e x o s S e t P r o c e s s S t a t e (DM PROCESS STATE LOADCFG) ; /∗ −−− s n i p −−− ∗/ Extreme Networks Confidential 49 5.7. ADDING EVENT LOGGING 5.7 CHAPTER 5. ADDING EMS SUPPORT Adding Event Logging With all the necessary prerequisites in place, we can now instrument our application to log the newly created event messages, as shown in Listing 5.6. Source Code Listings 5.6: Adding logging for email events /∗ −−− s n i p −−− ∗/ s t a t i c void sampleSendMailCB ( void ∗ arg1 , void ∗ a r g 2 ) { int r c ; char ∗ s e r v e r = ” 1 0 . 5 . 2 . 1 5 8 ” ; char ∗ a d d r e s s = ” l r i c h a r d s o n @ S y z y g y −HLR” ; DR AF T emsTraceLogf ( debug handle , 0 , ” Entered sampleSendMailCB ( ) ” ) ; rc = smtp post ( server , ” 10.66.4.10 ” , ” someone@somecorp . com” , address , ” H e l l o , world ! \ n” ) ; emsTraceLogf ( debug handle , 0 , ” s m t p p o s t ( ) r e t u r n e d %d” , r c ) ; switch ( r c ) { case 0 : /∗ s u c c e s s ∗/ EMS sample EMailSent ( a d d r e s s , s e r v e r ) ; break ; case −1: /∗ s o c k e t ( ) or s e t s o c k o p t ( ) f a i l e d ∗/ EMS sample EMailSendFailed ( a d d r e s s , s e r v e r , ” socket operation f a i l e d ”) ; break ; case −2: /∗ g e t h o s t b y n a m e ( ) f a i l e d ∗/ EMS sample EMailSendFailed ( a d d r e s s , s e r v e r , ” c o u l d not r e s o l v e s e r v e r a d d r e s s ” ) ; break ; case −3: /∗ c o n n e c t ( ) f a i l e d ∗/ EMS sample EMailSendFailed ( a d d r e s s , s e r v e r , ” c o u l d not e s t a b l i s h c o n n e c t i o n t o s e r v e r ” ) ; break ; default : /∗ p r o t o c o l e r r o r or c o n n e c t i o n l o s s ∗/ EMS sample EMailSendFailed ( a d d r e s s , s e r v e r , ” p r o t o c o l e r r o r or connection l o s s ” ) ; break ; } } /∗ −−− s n i p −−− ∗/ 50 Extreme Networks Confidential Chapter 6 6.1 T VLAN Manager Overview 6.2 DR AF This chapter continues our tutorial development of an EXOS native application using the EXOS application SDK. In this chapter we introduce the VLAN Manager API with examples of its use to monitor changes to VLAN configuration. VLAN Manager API The EXOS VLAN Manager application is responsible for maintaining and coordinating numerous aspects of VLAN configuration and run-time status, including: • VLAN creation, deletion, and tagging configuration. • VLAN port membership and port state. • L3 interface information. • Virtual router instances. • Physical port configuration and status. The VLAN Manager APIs enable EXOS applications to retrieve information maintained by VLAN manager when needed and to monitor changes to this information. 6.3 Using VLAN Manager APIs Code related to the use of VLAN manager APIs will be contained in a new file, sample vlan.c, which is shown in Figure 6.1 and summarized as follows: • Line 1 includes maininc.h, as described in Chapter 2 previously. • Line 2 includes the VLAN API definition header file vlanApi.h. 51 6.3. USING VLAN MANAGER APIS CHAPTER 6. VLAN MANAGER • Line 3 includes a new header file for the sample application, the contents of which are shown in Figure 6.2. • Lines 5-17 define a callback function to be called when a new VLAN has been created. • Lines 19-26 define a callback function to be called when a VLAN is being deleted. • Lines 28-37 define a callback function to be called when the 802.1q VLAN tag value has been changed. T • Lines 39-51 contain the code required to initialize the VLAN manager API for the sample application. First the clientProcessInfo t structure is initialized with non-NULL callback function pointers for all desired events, then connectToVlanMgr() is called to initialize the API library. Note that the first parameter to this function specifies which databases should be populated locally, in this case both L2 and L3 information will be maintained locally. Source Code Listings 6.1: VLAN Manager Interface DR AF 1 #include ” maininc . h” 2 #include ” l 2 p r o t o c o l / v l a n / i n c / vlanApi . h” 3 #include ” . . / i n c / sample . h” 4 5 /∗ C a l l b a c k f u n c t i o n f o r ” c r e a t e v l a n ” e v e n t s ∗/ 6 int c r e a t e v l a n c b ( u i n t 8 t ∗ vlan name , 7 uint32 t vlan if instance , 8 uint16 t vlan tag , 9 uint16 t tag status , 10 uint32 t kernel if index , 11 u i n t 8 t ∗ vr name , 12 uint32 t vr id ) 13 { 14 emsTraceLogf ( debug handle , 0 , ” [ c r e a t e v l a n ] name : %s t a g : %d vr : %s \n” , 15 vlan name , v l a n t a g , vr name ) ; 16 return 1 ; 17 } 18 19 /∗ C a l l b a c k f u n c t i o n f o r ” d e l e t e v l a n ” e v e n t s ∗/ 20 int r e m o v e v l a n c b ( u i n t 8 t ∗ vlan name , 21 uint32 t vlan if instance , 22 uint32 t kernel if index ) 23 { 24 emsTraceLogf ( debug handle , 0 , ” [ r e m o v e v l a n ] name : %s \n” , vlan name ) ; 25 return 1 ; 26 } 27 28 /∗ C a l l b a c k f u n c t i o n f o r ” c o n f i g u r e v l a n t a g ” e v e n t s ∗/ 29 int c o n f i g v l a n t a g c b ( u i n t 8 t ∗ vlan name , 30 uint32 t vlan if instance , 31 uint32 t kernel if index , 32 uint16 t vlan tag ) 33 { 34 emsTraceLogf ( debug handle , 0 , ” [ c o n f i g v l a n t a g ] name : %s t a g : %d\n” , 52 Extreme Networks Confidential CHAPTER 6. VLAN MANAGER vlan name , v l a n t a g ) ; return 1 ; } /∗ Function t o i n i t i a l i z e t h e a p p l i c a t i o n ’ s i n t e r f a c e t o VLAN manager ∗/ void s a m p l e v l a n i n i t ( void ) { clientProcessInfo t info ; memset (& i n f o , 0 , s i z e o f i n f o ) ; i n f o . fnPtrCreateVlan = create vlan cb ; i n f o . fnPtrRemoveVlan = remove vlan cb ; i n f o . fnPtrCfgTagToVlan = c o n f i g v l a n t a g c b ; connectToVlanMgr (DB LIB VLAN L2 SUPPORT | DB LIB VLAN L3 SUPPORT , &i n f o ) ; } T 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 6.4. THE VLAN MANAGER APIS IN ACTION Source Code Listings 6.2: Sample Application Definitions /∗ VLAN Manager c l i e n t l i b r a r y i n i t i a l i z a t i o n ∗/ extern void s a m p l e v l a n i n i t ( void ) ; DR AF 1 2 3 4 5 /∗ EMS t r a c e b u f f e r h a n d l e ∗/ extern void ∗ d e b u g h a n d l e ; 6.4 The VLAN Manager APIs in Action Each callback function simply logs a portion of its parameters to the debug trace buffer, which can be displayed as usual via the CLI command: debug ems show trace sample debug Extreme Networks Confidential 53 CHAPTER 6. VLAN MANAGER DR AF T 6.4. THE VLAN MANAGER APIS IN ACTION 54 Extreme Networks Confidential Chapter 7 7.1 T FDB Manager Overview 7.2 DR AF This chapter continues our tutorial development of an EXOS native application using the EXOS application SDK. In this chapter we introduce the FDB Manager API with examples of its use to manage application-specific static FDBs. FDB Manager API The EXOS FDB Manager application is responsible for maintaining and reporting information related to the Layer 2 FDB, including static and dynamic FDB entries, filters for various MAC addresses requiring special handling (STP, LLDP, etc.), and address resolution tables. The FDB Manager APIs enable EXOS applications to retrieve information maintained by the FDB manager and to manage application-specific FDB entries. 7.3 Using FDB Manager APIs Code related to the use of FDB manager APIs will be contained in a new file, sample fdb.c, which is shown in Figure 7.1 and summarized as follows: Source Code Listings 7.1: FDB Manager Interface 1 2 3 4 5 6 7 8 9 10 11 12 #include #include #include #include ” maininc . h” ” l 2 p r o t o c o l / fdb / i n c / f d b c l i e n t . h” ” l 2 p r o t o c o l / fdb / i n c / f d b c l i e n t a p i . h” ” . . / i n c / sample . h” s t a t i c FDB CLIENT ERROR f d b c b (FDB CLIENT CALLBACK code , f d b c l i e n t c a l l b a c k a r g t ∗ arg ) { switch ( code ) { case FDB CLIENT CALLBACK CONNECT : f d b c l i e n t T y p e (FDB CLIENT GENERAL) ; break ; default : 55 7.4. THE FDB MANAGER APIS IN ACTION break ; } return FDB CLIENT ERROR NONE ; } /∗ Function t o i n i t i a l i z e t h e a p p l i c a t i o n ’ s i n t e r f a c e t o FDB manager ∗/ void s a m p l e f d b i n i t ( void ) { f d b c l i e n t I n i t ( f d b c b , TRUE) ; } The FDB Manager APIs in Action T 7.4 DR AF 13 14 15 16 17 18 19 20 21 22 CHAPTER 7. FDB MANAGER 56 Extreme Networks Confidential Chapter 8 8.1 T L2 Packet Handling Overview DR AF In this chapter a small application is developed to demonstrate the use of packet sockets for the sending and receiving L2 Ethernet packets by an EXOS application. Two primary functions are implemented in this application: • Sending of WoL (Wake-on-LAN) packets when initiated by a CLI command. • Logging of received WoL packets to a trace buffer. 8.2 Application Source Code Listings 8.1: Wake-on-LAN Application 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include #include #include #include #include #include ” maininc . h” ” c l i s u b a g e n t . h” ” . . / i n c / sample . h” ” . . / i n c / s a m p l e o b j d e f . h” ” l 2 p r o t o c o l / v l a n / i n c / vlanApi . h” ” k e r n e l m o d u l e s / n e t t x / i n c / nettx common . h” #include <l i n u x / f i l t e r . h> #include <l i n u x / i f e t h e r . h> #include <l i n u x / i f p a c k e t . h> /∗ D e f i n e s t r u c t u r e o f Wake−on−LAN P a c k et ∗/ struct woLPacket { u i n t 8 t da [ ETH ALEN ] ; u i n t 8 t s a [ ETH ALEN ] ; u i n t 1 6 t dot1qType ; u i n t 1 6 t dot1qTag ; u i n t 1 6 t etherType ; u i n t 8 t sync [ 6 ] ; u i n t 8 t tmacs [ 1 6 ] [ ETH ALEN ] ; }; 57 8.2. APPLICATION 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 /∗ EMS t r a c e b u f f e r h a n d l e ∗/ void ∗ d e b u g h a n d l e = NULL; /∗ PF EXOS PACKET s o c k e t d e s c r i p t o r ∗/ int s o c k f d = −1; T /∗ ∗ Dispatcher c a l l b a c k for socket readable event ∗/ void p k t r x ( void ∗ arg , void ∗ svc , i p m l P e e r I d t peer , i p m l P a c k e t t ∗ pkt , int b y t e s ) { uint8 t buffer [2048]; int rc ; struct msghdr msg ; struct s o c k a d d r l l e x p k t r e c v s l l ; struct i o v e c iov [ 1 ] ; memset(&msg , 0 , s i z e o f msg ) ; iov [ 0 ] . iov base = buffer ; iov [ 0 ] . iov len = sizeof buffer ; DR AF 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 CHAPTER 8. L2 PACKET HANDLING msg . m s g i o v msg . m s g i o v l e n msg . msg name msg . msg namelen = = = = iov ; 1; &s l l ; sizeof s l l ; r c = recvmsg ( s o c k f d , &msg , 0 ) ; i f ( rc < 0) { emsTraceLogf ( debug handle , 0 , ” r e c e i v e f a i l e d , e r r n o %d(%s ) \n” , e r r n o , s t r e r r o r ( e r r n o ) ) ; } else { emsTraceLogf ( debug handle , 0 , ” r e c e i v e d %d b y t e s v i a f i l t e r %d on %d:%d\n” , rc , s l l . f i l t e r I d , GET SLOT( s l l . l i f P o r t ) , GET PORT( s l l . l i f P o r t ) ); } } /∗ ∗ I n i t i a l i z e PF EXOS PACKET s o c k e t f o r t r a n s m i t and r e c e i v e . ∗/ void i n i t P a c k e t I n t e r f a c e ( void ) { expktFilter t f i l t e r ; dispatchAttrib t attr ; int r c ; s o c k f d = s o c k e t (PF EXOS PACKET, SOCK RAW, h t o n s (ETH P ALL) ) ; i f ( sockfd < 0) { emsTraceLogf ( debug handle , 0 , ” s o c k e t ( ) f a i l e d , e r r n o %d\n” , e r r n o ) ; return ; } 58 Extreme Networks Confidential CHAPTER 8. L2 PACKET HANDLING 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 memset(& f i l t e r , 0 , s i z e o f f i l t e r ) ; filter filter filter filter filter . filterType . interfaceType . hwAction . matchedAction . ingressMatchedAction filter filter filter filter . vid . keyLength . key [ 0 ] . key [ 1 ] = = = = = = = = = POST BLOCK FILTER ; INTERFACE PIF ; HWFORWARD; UP AND CONTINUE ; UP AND CONTINUE ; 0xFFFF ; /∗ match any VLAN ∗/ 2; 0 x08 ; /∗ Match E t h e r t y p e 0 x0842 ∗/ 0 x42 ; T rc = setsockopt ( sockfd , SOL EXOS PACKET, SO EXOS ATTACH FILTER, &f i l t e r , sizeof f i l t e r ) ; i f ( rc < 0) { emsTraceLogf ( debug handle , 0 , ” s e t s o c k o p t ( ) a t t a c h f i l t e r f a i l e d , e r r n o %d\n ” , errno ) ; close ( sockfd ) ; return ; } else { emsTraceLogf ( debug handle , 0 , ” a t t a c h e d f i l t e r , i d %d\n” , f i l t e r . f i l t e r I d ) ; } DR AF 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 8.2. APPLICATION memset(& a t t r , 0 , s i z e o f a t t r ) ; a t t r . func = pktrx ; s t r c p y ( a t t r . s t r i n g , ” Packet R e c e i v e ” ) ; d i s p a t c h A d d F i l e (& a t t r , s o c k f d ) ; emsTraceLogf ( debug handle , 0 , ” S u c c e s s f u l l y i n i t i a l i z e d p a c k e t i n t e r f a c e \n” ) ; } /∗ ∗ Send a Wake−on−LAN p a c k e t f o r t h e s p e c i f i e d MAC a d d r e s s ∗ and VLAN. ∗/ void sendWoLPacket ( char ∗ vlan , unsigned char ∗mac ) { int rc ; struct msghdr msg ; struct i o v e c iov [ 1 ] ; struct s o c k a d d r l l e x p k t s e n d slls ; struct woLPacket pkt ; int i ; vlanIf t ∗ vlanIf ; i f ( getVlanIfByName ( vlan , &v l a n I f ) != VLAN SUCCESS) { return ; } memset(& s l l s , 0 , s i z e o f s l l s ) ; memset(&msg , 0 , s i z e o f msg ) ; Extreme Networks Confidential 59 8.2. APPLICATION = &pkt ; = s i z e o f pkt ; slls slls slls slls = = = = PF EXOS PACKET ; EXPKT TRANSMIT BY VLAN ; EXOS INVALID PRIORITY ; v l a n I f −>l 2 c i f I n s t a n c e ; = = = = iov ; 1; &s l l s ; s i z e o f ( struct s o c k a d d r l l e x p k t s e n d ) ; . sll family . transmitCmd . cpu priority . vlanInstance msg . m s g i o v msg . m s g i o v l e n msg . msg name msg . msg namelen /∗ C o n s t r u c t WoL P a ck e t ∗/ memset ( pkt . da , 0xFF , ETH ALEN) ; getSystemMac ( pkt . sa , 0 ) ; pkt . dot1qType = h t o n s ( 0 x8100 ) ; pkt . dot1qTag = h t o n s ( v l a n I f −>v l a n I d ) ; pkt . etherType = h t o n s ( 0 x0842 ) ; memset ( pkt . sync , 0xFF , s i z e o f pkt . sync ) ; f o r ( i =0; i < 1 6 ; i ++) memcpy ( pkt . tmacs [ i ] , mac , ETH ALEN) ; T iov [ 0 ] . iov base iov [ 0 ] . iov len DR AF 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 CHAPTER 8. L2 PACKET HANDLING r c = sendmsg ( s o c k f d , &msg , 0 ) ; } /∗ ∗ C a l l b a c k f u n c t i o n t o h a n d l e c o n f i g u r a t i o n manager c l i e n t e v e n t s . ∗/ s t a t i c int cmBackendEventHandler ( cmBackendEvent e event , void ∗ c o o k i e ) { int r c = CM BACKEND SUCCESS; switch ( e v e n t ) { case CM BACKEND EVENT LOAD COMPLETE: /∗ C o n f i g u r a t i o n l o a d i s c ompl ete , move p r o c e s s s t a t e t o ” r e a d y ” ∗/ e x o s S e t P r o c e s s S t a t e (DM PROCESS STATE READY) ; break ; case CM BACKEND EVENT GENERATE DEFAULT: /∗ D e f a u l t c o n f i g u r a t i o n case , move p r o c e s s s t a t e t o ” r e a d y ” ∗/ e x o s S e t P r o c e s s S t a t e (DM PROCESS STATE READY) ; break ; default : break ; } return r c ; } /∗ ∗ C a l l b a c k f u n c t i o n t o h a n d l e d e v i c e manager c l i e n t e v e n t s . 60 Extreme Networks Confidential CHAPTER 8. L2 PACKET HANDLING /∗ ∗ Main e n t r y p o i n t t o sample EXOS a p p l i c a t i o n . ∗/ int main ( int argc , char ∗∗ argv ) { clientProcessInfo t info ; T ∗/ s t a t i c void dmHandler ( i p m l P e e r I d t peer , int msg id , int obj , int p1 , void ∗p2 ) { switch ( msg id ) { case DM MSG LOAD CFG: /∗ R e q u e s t c o n f i g u r a t i o n from t h e c o n f i g u r a t i o n manager p r o c e s s ∗/ CM BACKEND REQUEST CONFIG; break ; } } /∗ I n i t i t i a l i z e p r o c e s s name from environment c r e a t e d by EPM ∗/ exosSetProcessName (NULL) ; DR AF 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 8.2. APPLICATION /∗ I n i t i a l i z e d e v i c e manager c l i e n t u s i n g dmHandler ( ) c a l l b a c k f u n c t i o n ∗/ dmInit ( 0 , dmHandler ) ; /∗ I n i t i a l i z e EPM c l i e n t ∗/ e p mC l i e n tS e t P i d ( ) ; /∗ I n i t i a l i z e EPM c l i e n t ∗/ /∗ I n i t i a l i z e p r o c e s s s t a t e ∗/ e x o s S e t P r o c e s s S t a t e (DM PROCESS STATE BOOTING) ; /∗ I n i t i a l i z e d i s p a t c h e r e v e n t h a n d l e r ∗/ d i s p a t c h I n i t (NULL, /∗ Use d e f a u l t p r o c e s s name ∗/ 0, /∗ Use d e f a u l t k e e p a l i v e i n t e r v a l ∗/ 0, /∗ No c h i l d t h r e a d s ∗/ NULL, /∗ Empty c h i l d t h r e a d a r r a y ∗/ DISPATCH NON THREADED) ; /∗ S i n g l e −t h r e a d e d a p p l i c a t i o n ∗/ e x o s S e t P r o c e s s S t a t e (DM PROCESS STATE LOADCFG) ; /∗ S t a r t c o n n e c t i o n t o d e v i c e manager ∗/ dmConnect ( ) ; /∗ I n i t i a l i z e CLI c l i e n t l i b r a r y ∗/ c l i S u b a g e n t I n i t ( exosGetProcessName ( ) , NULL) ; /∗ I n i t i a l i z e c o n f i g u r a t i o n manager c l i e n t l i b r a r y w i t h e v e n t h a n d l e r ∗/ cmBackendInit ( exosGetProcessName ( ) , cmBackendEventHandler ) ; /∗ I n i t i a l i z e VLAN API ∗/ memset (& i n f o , 0 , s i z e o f i n f o ) ; connectToVlanMgr (DB LIB VLAN L2 SUPPORT , &i n f o ) ; Extreme Networks Confidential 61 8.2. APPLICATION 237 238 239 240 241 242 243 244 245 246 247 CHAPTER 8. L2 PACKET HANDLING d e b u g h a n d l e = e m s I n i t T r a c e B u f f e r ( ” debug ” , 8 1 9 2 , NULL) ; /∗ I n i t i a l i z e p a c k e t t x / r c i n t e r f a c e ∗/ initPacketInterface () ; /∗ Enter i n f i n i t e e v e n t h a n d l i n g l o o p ∗/ emsTraceLogf ( debug handle , 0 , ” C a l l i n g d i s p a t c h H a n d l e r ( ) ” ) ; dispatchHandler () ; exit (0) ; } Source Code Listings 8.2: WoL Applications CM Methods ” maininc . h” ” c l i s u b a g e n t . h” ” . . / i n c / sample . h” ” . . / i n c / s a m p l e o b j d e f . h” T #include #include #include #include int sendWoL t set ( cmBackendContext t ∗ ctx , sendWoL t ∗ i n ) { i f ( SENDWOL T IS VALID( in , mac ) && SENDWOL T IS VALID( in , v l a n ) ) { sendWoLPacket ( in−>vlan , in−>mac . mac ) ; } DR AF 1 2 3 4 5 6 7 8 9 10 11 12 13 return CM BACKEND SUCCESS; } Source Code Listings 8.3: WoL Applications CM Object Definiitons 1 2 3 4 5 struct sendWoL t { char v l a n [ 3 3 ] ; mac t mac ; method s e t ; } sendWoL ; Source Code Listings 8.4: WoL Applications CLI Definiitons 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 %namespace= ”vlanName”% %endnamespace% %s t y l e = ” extreme ”% %command=” run wake−on−lan v l a n <vlan> mac−address <mac>”% %a t t r i b u t e% %wake−on−lan => help= ” Send a wake−on−LAN p a c k e t ”;% %v l a n => help= ”VLAN”;% %<vlan> => help= ”VLAN” ; type= ”vlanName”;% %mac−address => help= ” S t a t i o n MAC a d d r e s s ”;% %<mac> => help= ”MAC Address ” ; type= ” mac t ”;% %e n d a t t r i b u t e% %action= ”xml”% array set a r g s $argv 62 Extreme Networks Confidential CHAPTER 8. L2 PACKET HANDLING 8.2. APPLICATION DR AF T 17 set xml ”<sendWoL><vlan>$ a r g s (<vlan >)</vlan><mac>$ a r g s (<mac>)</mac></sendWoL>” 18 19 set r e p l y [ s e t o n e ” sample ” $xml ] 20 b u i l d a r r a y $ r e p l y −indexed 21 22 i f { [ string e q u a l $xmlData ( r e p l y . 0 . s t a t u s . 0 ) {ERROR} ] } { 23 show ” $xmlData ( r e p l y . 0 . m e s s a g e . 0 ) \n” 24 } 25 26 unset a r g s xml r e p l y 27 %e n d a c t i o n% 28 %endcommand% 29 %e n d s t y l e% Extreme Networks Confidential 63 CHAPTER 8. L2 PACKET HANDLING DR AF T 8.2. APPLICATION 64 Extreme Networks Confidential Chapter 9 9.1 T Linux Kernel Modules Overview 9.2 DR AF This chapter introduces the infrastructure for building loadable kernel modules within the EXOS native SDK framework. Kernel Module Makefile Figure 9.1 contains the makefile for a trivial kernel module, nullmod.ko. Source Code Listings 9.1: Linux Kernel Module Makefile 1 i f e q ( $ (KERNELRELEASE) , ) 2 3 include $ (SDKBASE) / e x o s / code / d e f s . mk 4 5 EXOS KMOD = nullmod 6 7 EXOS KMOD SRC = nullmod main . c 8 9 EXOS KMOD CFLAGS = $ (EXOS KMOD COMMON CFLAGS) 10 11 include $ (SDKBASE) / e x o s / code / e x t e r n l k m . mk 12 include $ (SDKBASE) / e x o s / code / r u l e s . mk 13 14 e l s e # KERNELRELEASE 15 include $ (SDKBASE) / e x o s / code / Kbuild . lkm 16 endif # KERNELRELEASE 9.3 Trivial Kernel Module Source Figure 9.2 contains the source code for the trivial kernel module, which does nothing more than register a /proc filesystem entry /proc/nullmod that returns the text nullmod present when read. Source Code Listings 9.2: Sample Application Definitions 65 9.3. TRIVIAL KERNEL MODULE SOURCE T /∗ ∗∗ ∗∗ Name : nullmod main . c ∗∗ ∗∗ Purpose : Do−n o t h i n g module t o d e m o n s t r a t e k e r n e l module b u i l d p r o c e s s . ∗∗ ∗/ #include <l i n u x / t y p e s . h> #include <l i n u x / s c h e d . h> #include <l i n u x /mm. h> #include <l i n u x / f c n t l . h> #include <l i n u x / i n . h> #include <l i n u x /kmod . h> #include <l i n u x / e r r n o . h> #include <l i n u x / t i m e r . h> #include <asm/ system . h> #include <asm/ u a c c e s s . h> #include <asm/ i o c t l s . h> #include <l i n u x / p r o c f s . h> #include <l i n u x / s e q f i l e . h> #include <l i n u x / s p i n l o c k . h> #include <l i n u x / p o l l . h> #include <l i n u x / module . h> #include <l i n u x / i n i t . h> DR AF 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 CHAPTER 9. LINUX KERNEL MODULES s t a t i c struct p r o c d i r e n t r y ∗ n m p r o c e n t r y ; s t a t i c int nm proc show ( struct s e q f i l e ∗m, void ∗v ) { s e q p r i n t f (m, ”%s \n” , ” nullmod p r e s e n t . ” ) ; return 0 ; } s t a t i c int nm proc open ( struct i n o d e ∗ inode , struct f i l e ∗ f i l e ) { return s i n g l e o p e n ( f i l e , nm proc show , NULL) ; } s t a t i c const struct f i l e o p e r a t i o n s n m p r o c f o p s = { . owner = THIS MODULE, . open = nm proc open , . read = seq read , . llseek = seq lseek , . release = single release , }; #define NULLMOD DESCR ” nullmod : 1 . 0 . 0 . 0 : ” MODULE DESCRIPTION(NULLMOD DESCR) ; s t a t i c int i n i t n u l l m o d i n i t ( void ) { int r c = 0 ; n m p r o c e n t r y = p r o c c r e a t e ( ” nullmod ” , S IRUGO , NULL, &n m p r o c f o p s ) ; 66 Extreme Networks Confidential CHAPTER 9. LINUX KERNEL MODULES 9.3. TRIVIAL KERNEL MODULE SOURCE DR AF T 55 56 i f ( n m p r o c e n t r y == NULL) 57 r c = −ENOMEM; 58 59 return r c ; 60 } 61 62 s t a t i c void e x i t n u l l m o d e x i t ( void ) 63 { 64 i f ( n m p r o c e n t r y != NULL) { 65 r e m o v e p r o c e n t r y ( ” nullmod ” , NULL) ; 66 } 67 } 68 69 m o d u l e i n i t ( n u l l m o d i n i t ) ; 70 m o d u l e e x i t ( n u l l m o d e x i t ) ; 71 MODULE LICENSE( ” Extreme Networks P r o p r i e t a r y ” ) ; Extreme Networks Confidential 67 Index CLI (Command-Line Interface) Architecture, 33 Definition File, 16 T Dispatcher, 28 Timers, 28 DM (Device Manager) Definition, 19 DR AF EMS (Event Management System), 43 Architecture, 43 Debug Trace Buffers, 29 Environment Variables SDKBASE, 10 EPM (EXOS Process Manager) Responsibilities, 14 Files cli, 16 epmrc, 17 Kernel Module Makefile, 65 Makefile, 21 obj, 16 spec, 16 version, 22 IPML (Inter-Process Messaging Layer) Architecture, 14 Loadable Kernel Modules, 65 SMTP (Simple Mail Transport Protocol) Client, 25 68
© Copyright 2024