loader-logo

WLC Code Upgrade Challenges

The writing is on the wall for on-premises wireless LAN controllers (WLCs). In the past, enterprises needed to purchase a wireless LAN controller to deploy, manage, and configure access points.

With the shift to cloud technologies, a WLC is no longer required. WLCs brought in additional overhead. WLCs are complex and challenging to manage. There is a high cost to purchasing a controller – the physical appliance and the licensing required to manage access points.

Let’s dive into some specific challenges induced by on-prem wireless LAN controllers.

On-Prem WLC

Not Enough Time

Business moves quickly. End-users are frustrated with technology that impedes their work. A significant amount of planning and preparation goes into upgrading a WLC.

A network engineer must peruse release notes to identify bugs and vulnerabilities with a specific WLC software version.

After identifying the desired software version, scheduling a maintenance window is also a challenge. The network engineer must wake up at an ungodly hour to perform the upgrade.

Upgrading a WLC involves upgrading the software on the access points. While the software can be pre-downloaded, sometimes it is forgotten. The time required to upgrade hundreds and even thousands of access points can take too long.

A WLC can only handle so many file downloads from access points at a given time. The network engineer crosses their fingers and prays to the wireless gods that the WLC comes back online as they wait for it to respond to pings.

The exact process applies to access points, hoping that not many will need replacing due to bad flashing or other boot-up issues.

Dealing With Open Caveats

Upgrading WLC software involves taking a calculated risk. An upgrade only occurs for a good reason. Either there is a bug to fix or a vulnerability to plug.

But open caveats are another reason to tread carefully with WLC software upgrades.

Sometimes, new bugs are introduced. Some create a high impact.

These new bugs cause headaches for network engineers and increase frustration for end-users.

Access Point Support

Don’t act too quickly on upgrading to the latest WLC version of the software.

Take inventory of which access points will be unsupported with the desired software version for large deployments.

Unsupported access points are usually due to age. They’ll be left stranded after the upgrade, unable to join the WLC.

An organization may be limited to a specific WLC software version.

The High Cost of High Availability

Network architecture requires redundancy and high availability. WLC falls under this category. If a sole WLC fails, all access points stop providing service to devices.

WLCs solve the single point of failure with N+1 to provide redundancy.

Often, one WLC serves the access points, with the other sitting idle as a backup.

The organization purchases two controllers—a waste of money. Higher cost to buy, higher costs to maintain and deal with licensing headaches.

Each WLC is independent of the other and managed separately.

The Efficient Way

Now’s the time to embrace cloud-native and cloud-managed Wi-Fi.

The time to deploy and be connected is instantaneous. Access points download their configuration from the cloud after acquiring Internet access.

Eliminate controllers. No more spending early morning maintenance windows to upgrade controllers and access points. Schedule software upgrades for access points without waking up at 3 am. And updates are under continuous development. A network operator can get new features, bug fixes, and security fixes faster.

Access points software is configurable to specific versions, so an access point won’t be left stranded no matter what “version” the cloud is using.

Controllers are no longer needed. High availability is in the cloud provider. Look for cloud-native technologies used, not just a cloud controller.

Make a move to cloud-native and cloud-managed Wi-Fi today!


4 thoughts on “WLC Code Upgrade Challenges”

  1. Lee Badman says:

    Let’s not forget this cycle: upgrade today, fallback tomorrow, escalation build, escalation build, fall back. Get fed up. Don’t upgrade again for 10 years because the vendor can’t figure out ANYTHING.

    1. Rowell Dionicio says:

      Another frustrating thing to spend hours on!

  2. I agree with your points and there’s often still a need to terminate CAPWAP / DTLS / GRE / IPsec data plane tunnels on-premises. This means still buying one or more (for HA) on-premises data plane tunnel terminators, e.g., what is seen with Juniper / Mist. The disruption from APs needing to download (ALWAYS pre-download if at ALL possible!) and reboot to upgrade their code is still a thing regardless of Cloud-native control and management planes. I’d say the more the AP code upgrades can be granularly controlled by an administrator, e.g., via AP groups, and the more Cloud-native architecture feature, like microservices, vs. monolithic embedded code in the APs, the better.

    1. Rowell Dionicio says:

      Good points, Michael. Although I will go out and say that most environments do not need any tunnels but if the requirement is there then yes, I agree. Code upgrades are getting easier but are still limited by on-prem. We have granularity with AP code upgrades going to cloud-managed APs. And we’ve just made it there now with on-prem controllers.

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.


[gravityforms id=16 title=false description=false]
<script type="text/javascript">var gform;gform||(document.addEventListener("gform_main_scripts_loaded",function(){gform.scriptsLoaded=!0}),window.addEventListener("DOMContentLoaded",function(){gform.domLoaded=!0}),gform={domLoaded:!1,scriptsLoaded:!1,initializeOnLoaded:function(o){gform.domLoaded&&gform.scriptsLoaded?o():!gform.domLoaded&&gform.scriptsLoaded?window.addEventListener("DOMContentLoaded",o):document.addEventListener("gform_main_scripts_loaded",o)},hooks:{action:{},filter:{}},addAction:function(o,n,r,t){gform.addHook("action",o,n,r,t)},addFilter:function(o,n,r,t){gform.addHook("filter",o,n,r,t)},doAction:function(o){gform.doHook("action",o,arguments)},applyFilters:function(o){return gform.doHook("filter",o,arguments)},removeAction:function(o,n){gform.removeHook("action",o,n)},removeFilter:function(o,n,r){gform.removeHook("filter",o,n,r)},addHook:function(o,n,r,t,i){null==gform.hooks[o][n]&&(gform.hooks[o][n]=[]);var e=gform.hooks[o][n];null==i&&(i=n+"_"+e.length),gform.hooks[o][n].push({tag:i,callable:r,priority:t=null==t?10:t})},doHook:function(n,o,r){var t;if(r=Array.prototype.slice.call(r,1),null!=gform.hooks[n][o]&&((o=gform.hooks[n][o]).sort(function(o,n){return o.priority-n.priority}),o.forEach(function(o){"function"!=typeof(t=o.callable)&&(t=window[t]),"action"==n?t.apply(null,r):r[0]=t.apply(null,r)})),"filter"==n)return r[0]},removeHook:function(o,n,t,i){var r;null!=gform.hooks[o][n]&&(r=(r=gform.hooks[o][n]).filter(function(o,n,r){return!!(null!=i&&i!=o.tag||null!=t&&t!=o.priority)}),gform.hooks[o][n]=r)}});</script> <div class='gf_browser_chrome gform_wrapper gravity-theme' id='gform_wrapper_16' ><form method='post' enctype='multipart/form-data' id='gform_16' action='/wlc-code-upgrade-challenges/' > <div class='gform_body gform-body'><div id='gform_fields_16' class='gform_fields top_label form_sublabel_below description_below'><fieldset id="field_16_1" class="gfield gfield_contains_required field_sublabel_below field_description_below gfield_visibility_visible" data-js-reload="field_16_1"><legend class='gfield_label gfield_label_before_complex' >Name<span class="gfield_required"><span class="gfield_required gfield_required_text">(Required)</span></span></legend><div class='ginput_complex ginput_container no_prefix has_first_name no_middle_name no_last_name no_suffix gf_name_has_1 ginput_container_name' id='input_16_1'> <span id='input_16_1_3_container' class='name_first' > <input type='text' name='input_1.3' id='input_16_1_3' value='' aria-required='true' placeholder='First Name' /> <label for='input_16_1_3' >First</label> </span> </div></fieldset><div id="field_16_2" class="gfield gfield--width-full gfield_contains_required field_sublabel_below field_description_below gfield_visibility_visible" data-js-reload="field_16_2"><label class='gfield_label' for='input_16_2' >Email<span class="gfield_required"><span class="gfield_required gfield_required_text">(Required)</span></span></label><div class='ginput_container ginput_container_email'> <input name='input_2' id='input_16_2' type='text' value='' class='large' placeholder='Business email address' aria-required="true" aria-invalid="false" /> </div></div><fieldset id="field_16_3" class="gfield gfield_contains_required field_sublabel_below field_description_below gfield_visibility_visible" data-js-reload="field_16_3"><legend class='gfield_label gfield_label_before_complex' >Consent<span class="gfield_required"><span class="gfield_required gfield_required_text">(Required)</span></span></legend><div class='ginput_container ginput_container_checkbox'><div class='gfield_checkbox' id='input_16_3'><div class='gchoice gchoice_16_3_1'> <input class='gfield-choice-input' name='input_3.1' type='checkbox' value='I consent to the processing and sharing with partners of the personal data that I provide Packet 6 for this activity in accordance with and as described in the &lt;a href=&quot;https://packet6.com/privacy-policy&quot; target=&quot;_new&quot;&gt;Privacy Policy&lt;/a&gt;' id='choice_16_3_1' /> <label for='choice_16_3_1' id='label_16_3_1'>I consent to the processing and sharing with partners of the personal data that I provide Packet 6 for this activity in accordance with and as described in the <a href="https://packet6.com/privacy-policy" target="_new">Privacy Policy</a></label> </div></div></div></fieldset><div id="field_16_4" class="gfield gform_validation_container field_sublabel_below field_description_below gfield_visibility_visible" data-js-reload="field_16_4"><label class='gfield_label' for='input_16_4' >Phone</label><div class='ginput_container'><input name='input_4' id='input_16_4' type='text' value='' /></div><div class='gfield_description' id='gfield_description_16_4'>This field is for validation purposes and should be left unchanged.</div></div></div></div> <div class='gform_footer top_label'> <input type='submit' id='gform_submit_button_16' class='gform_button button' value='Get the report' onclick='if(window["gf_submitting_16"]){return false;} window["gf_submitting_16"]=true; ' onkeypress='if( event.keyCode == 13 ){ if(window["gf_submitting_16"]){return false;} window["gf_submitting_16"]=true; jQuery("#gform_16").trigger("submit",[true]); }' /> <input type='hidden' class='gform_hidden' name='is_submit_16' value='1' /> <input type='hidden' class='gform_hidden' name='gform_submit' value='16' /> <input type='hidden' class='gform_hidden' name='gform_unique_id' value='' /> <input type='hidden' class='gform_hidden' name='state_16' value='WyJbXSIsImY4MGVlNTA5MGVjMWYzYzU5NzUyOGFhOWE3ZGFiMzRlIl0=' /> <input type='hidden' class='gform_hidden' name='gform_target_page_number_16' id='gform_target_page_number_16' value='0' /> <input type='hidden' class='gform_hidden' name='gform_source_page_number_16' id='gform_source_page_number_16' value='1' /> <input type='hidden' name='gform_field_values' value='' /> </div> <p style="display: none !important;"><label>&#916;<textarea name="ak_hp_textarea" cols="45" rows="8" maxlength="100"></textarea></label><input type="hidden" id="ak_js_2" name="ak_js" value="33"/><script>document.getElementById( "ak_js_2" ).setAttribute( "value", ( new Date() ).getTime() );</script></p></form> </div>